home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
askden
/
source
/
askden2.s
< prev
next >
Wrap
Text File
|
1999-04-05
|
80KB
|
3,600 lines
******************************************************************************
* ASK3アクセサリ ASKDen V2.02
* Copyright 1998-99 by AIG-Soft
******************************************************************************
.include defines.mac
.include fefunc.mac * 整数/実数演算を使う
.include pspdef.mac
.include ask3.mac
.cpu 68000
******************************************************************************
* 常駐ルーチン
******************************************************************************
* 年号をわざわざテキストでなしにバイナリー化しているのは、テキストのみより
* 誤った一致をしにくいから
.text
.even
KEEP_START:
varad .dc.l 0 * varのアドレスが入る(Den2Var用)
* 常駐確認用識別子
id: .dc.b 'ASKDen V2.02',19,99,'AIG-Soft',0
******************************************************************************
* 定数表
******************************************************************************
ACCS equ 2 * 全アクセサリの数
BMAX equ 4 * basesの個数
*
FeMin equ $fe00 * FLOAT?.Xのコールコード最小値
Yuketa equ 6 * 32ビット単精度実数の有効桁数
* 実験の結果より6桁なら大丈夫らしい
* 変数関係
VTYPE equ %1_1111 * 変数型(32種類)
VKAKU equ BIT7 * 0=確定 , 1=未確定
VDAI equ BIT6 * 0=再代入可 , 1=不可
BVDAI equ 6 * VDAIのビット番号
V_INT equ 0 * 0=整数数値(すべての演算可能)
V_FLOAT equ 1 * 1=単精度実数
*
VTOP equ 2 * 変数格納先頭位置:ハッシュの関係で0は使えない
*
* 演算子内部コード
VMINUS equ '@' * マイナス
VRSHIFT equ (('>'<<8)|'>') * 右シフト
VLSHIFT equ (('<'<<8)|'<') * 右シフト
VGE equ (('>'<<8)|'=') * 大なりイコール
VLE equ (('<'<<8)|'=') * 小なりイコール
VEQU equ (('='<<8)|'=') * イコール
VNE equ (('!'<<8)|'=') * not イコール
VRROT equ (('-'<<8)|'>') * 右ローテート
VLROT equ (('<'<<8)|'-') * 右ローテート
VINC equ (('+'<<8)|'+') * +1
VDEC equ (('-'<<8)|'-') * -1
VBEKI equ (('*'<<8)|'*') * べき乗
VAND equ (('&'<<8)|'&') * 論理AND
VOR equ (('|'<<8)|'|') * 論理OR
* 式系のエラー
VSNONE equ 1 * 数値/変数がない
VSDBL equ 2 * DouBLe 数値/変数が2つ続いている
VSOEN equ 3 * Only Enzan 演算子のみ
VSILL equ 4 * ILLegal 式がおかしい
VSCPXS equ 5 * ComPleX Suuti 式が複雑すぎる(数値/変数)
VSCPXE equ 6 * ComPleX Enzan 式が複雑すぎる(演算子)
VSCPXC equ 7 * ComPlex C 式が複雑すぎる(括弧)
VSCNONE equ 8 * (がない
VSENONE equ 9 * (の前に演算子がない
VSNNONE equ 10 * Naka NONE ()内がない
VSCILL equ 11 * ()内の式がおかしい
VSCNENG equ 12 * Not Enough )が足りない
VSNUMST equ 13 * Num STore 数値に代入しようとした
VSCHERR equ 14 * 文字コードが'で括られていない
VSNOFILE equ 15 * 式ファイルが見つからない(ASKDen)
VSLONG equ 16 * 式が長すぎる(ASKDen)
VSIONLY equ 17 * 整数モードでしか使えない(ASKDen2)
VSFONLY equ 18 * 実数モードでしか使えない(ASKDen2)
VS0DIV equ 20 * 0で除算した
VSOVER equ 21 * オーバーフロー
VSUNDER equ 22 * アンダーフロー
VSARG equ 23 * 引数がおかしい
* 変数系のエラー
VARNDEF equ 50 * No Define 変数が未定義
VARNST equ 51 * No STore 未確定変数への代入がない
VAROST equ 52 * Only STore 未確定変数には代入しか出来ない
VARLONG equ 53 * 変数名が長すぎ
VAROVER equ 54 * 変数はこれ以上定義出来ない
VARNMEM equ 55 * 変数処理用メモリーが足りない
VARNKAKU equ 56 * No KAKUtei 変数が未確定
VARDBL equ 57 * 変数が2重定義された
VARILL equ 58 * 変数名が異常
VARCSTA equ 59 * Can't STore Again 再代入不可変数に代入しようとした
VARTYPE equ 60 * 変数の型が違う
VARNAC equ 61 * 未確定変数にアクセスした
VARNKAKUR equ 62 * No KAKUtei Remain 未確定変数が残っている
VARAROVER equ 63 * 変数エリアを越えている
VARCCINT equ 64 * Can't Convert INTeger 整数化出来ない
* <128なのでmoveq.lで代入出来る
******************************************************************************
* ワーク1
******************************************************************************
* このワークエリアは起動時に初期値が必要/初期化時に利用するものである。
*
.even
ACh .dcb.l ACCS,-1 * アクセサリ(初期値-1<0)
* 正常登録された時、ACh[]>=0になる(0,1,2,3...)
all .dc.l 0 * 全ワークエリアサイズ
bases .dc.b 10,16,2,8 * 進数テーブル(良く使う順)
base: .dc.w 0 * 10進数(bases[base])
hugo .dc.b $ff * 0=符号なし,$ff=符号有り
fhigh .dc.b 0 * 0=低位メモリー確保,$ff=高位メモリー確保
first .dc.b 1 * 0=No,1=Yes,$ff=エラー発生直後
ffloat .dc.b 0 * 0=32bit整数,$ff=単精度実数
fnai .dc.b 0 * 0=整数化,$ff=内部表現
fzen .dc.b 0 * 0=半角出力,$ff=全角出力
ftei .dc.b 0 * 0=普通変数、$ff=定数(起動時式ファイル)
*
preexecI .ds.b 90 * 整数 式ファイル名
preexecF .ds.b 90 * 実数 式ファイル名
.even
fsizeI .dc.l -1 * 整数 式ファイルチェック用
fdateI .dc.w -1 *
ftimeI .dc.w -1 *
*
fsizeF .dc.l -1 * 整数 式ファイルチェック用
fdateF .dc.w -1 *
ftimeF .dc.w -1 *
* 構造体;実体
Vsikis * 式構造体
.dc.w 30 *0 short emax
.dc.w 30 *2 short vmax
.dc.w 0 *4 short es
.dc.w 0 *6 short vs
.ds.l 1 *8 unsint *estack
.ds.l 1 *12 long/float *vstack
.ds.l 1 *16 long *pstack
*
var * 変数構造体
.dc.l 0 *0 unchar *vwork ワークエリア先頭アドレス(初期値は0=確保してない)
.ds.l 1 *4 long vwsize
.dc.l 2 *8 long vpoint 変数格納先頭位置:ハッシュの都合で0は使えない
.dc.l 0 *12 long vlots
.ds.l 1 *16 long *vhash
.ds.w 1 *20 unsint vhsize
.dc.w 32 *22 unsint vlmax 変数名最大長
.dc.w 0 *24 unsint mode
.even
******************************************************************************
* オフセット表
******************************************************************************
* オフセットで書かれている部分もあれば即値で書かれている部分もあるので変更しないこと。
* 構造体;オフセット表
.offset 0
* 変数構造体
vwork .ds.l 1 * unchar *vwork
vwsize .ds.l 1 * long vwsize
vpoint .ds.l 1 * long vpoint
vlots .ds.l 1 * long vlots
vhash .ds.l 1 * long *vhash
vhsize .ds.w 1 * unsint vhsize
vlmax .ds.w 1 * unsint vlmax
mode .ds.w 1 * unsint mode
.offset 0
* 式構造体
emax .ds.w 1 * short emax
vmax .ds.w 1 * short vmax
es .ds.w 1 * short es
vs .ds.w 1 * short vs
estack .ds.l 1 * unsint *estack
vstack .ds.l 1 * long/float *vstack
pstack .ds.l 1 * long *pstack
.offset 0
* 変数格納オフセット
* len mode num name[00]
* 1 1 4 len+1 size
* 0 1 2 6 6+len+1 offset
Vlen .ds.b 1
Vmd .ds.b 1
Vnum .ds.l 1
Vname
.text
sizeV equ Vname * len+mode+numのサイズ
******************************************************************************
* メッセージ
******************************************************************************
Title .dc.b '+00進/整数 ',0
* 01234567890 ← 一部書き換わる
* 0=+/-(符号) , 12=10/02/16/08 , 67=整/実 , 10=' '/*:実数内部表現
MesError .dc.b ':',0
* var_dumpで利用
CrLf2: .dc.b CR,LF,0
MesMikaku: .dc.b '[未確定]',0 * 今のバージョンでは仮確定するから出ないはずだけど
MesTeisu: .dc.b '[定数]',0
MesDeni: .dc.b '整数',0 * 起動メッセージでも使う
MesDenf: .dc.b '実数',0 * 起動メッセージでも使う
Bsym .dc.b ' $%@',0 * 進数シンボル(baseの順)
*---------------------------------------------
* エラーメッセージ群
*---------------------------------------------
* 使われていないエラーメッセージもあるかも
*
InErr .dc.b '内部エラー;ご連絡下さい',0
ERRmes:
MVSNONE: .dc.b '数値/変数がない',0
MVSDBL: .dc.b '数値/変数が2つ続いている',0
MVSOEN: .dc.b '演算子のみ',0
MVSILL: .dc.b '式が異常',0
MVSCPXS: .dc.b '式が複雑すぎる(数値/変数)',0
MVSCPXE: .dc.b '式が複雑すぎる(演算子)',0
MVSCPXC: .dc.b '式が複雑すぎる(括弧)',0
MVSCNONE: .dc.b '(がない',0
MVSENONE: .dc.b '(の前に演算子がない',0
MVSNNONE: .dc.b '()内がない',0
MVSCILL: .dc.b '()内の式が異常',0
MVSCNENG: .dc.b ')が足りない',0
MVSNUMST: .dc.b '数値に代入しようとした',0
MVSCHERR: .dc.b '文字コードが',$27,'で括られていない',0
MVSNOFILE: .dc.b '式ファイルが見つからない',0
MVSLONG: .dc.b '式が長すぎる',0
MVSIONLY .dc.b '整数モードでしか使えない',0 * float
MVSFONLY .dc.b '実数モードでしか使えない',0 * float
MVS0DIV .dc.b '0で除算した',0
MVSOVER .dc.b 'オーバーフロー',0
MVSUNDER .dc.b 'アンダーフロー',0
MVSARG .dc.b '引数がおかしい',0
*
MVARNDEF: .dc.b '変数が未定義',0
MVARNST: .dc.b '未確定変数への代入がない',0
MVAROST: .dc.b '未確定変数には代入しか出来ない',0
MVARLONG: .dc.b '変数名が長すぎる',0
MVAROVER: .dc.b '変数はこれ以上定義出来ない',0
MVARNMEM: .dc.b '変数処理メモリーが足りない',0
MVARNKAKU: .dc.b '変数が未確定',0
MVARDBL: .dc.b '変数が2重定義された',0
MVARILL: .dc.b '変数名が異常',0
MVARCSTA: .dc.b '定数に代入する',0 * 再代入不可変数
MVARTYPE: .dc.b '変数の型が違う',0
MVARNAC: .dc.b '未確定変数にアクセスした',0
MVARNKAKUR: .dc.b '未確定変数が残っている',0
MVARAROVER: .dc.b '変数エリアを越える',0
MVARCCINT .dc.b '整数化出来ない',0
.even
*---------------------------------------------
* エラーコード表(上のメッセージと同じ順)
*---------------------------------------------
ERRvsiki:
.dc.w VSNONE,VSDBL,VSOEN,VSILL,VSCPXS,VSCPXE,VSCPXC,VSCNONE,VSENONE,VSNNONE
.dc.w VSCILL,VSCNENG,VSNUMST,VSCHERR,VSNOFILE,VSLONG
* 実数版で追加
.dc.w VSIONLY,VSFONLY,VS0DIV,VSOVER,VSUNDER,VSARG
*
.dc.w VARNDEF,VARNST,VAROST,VARLONG,VAROVER,VARNMEM,VARNKAKU,VARDBL,VARILL
.dc.w VARCSTA,VARTYPE,VARNAC,VARNKAKUR,VARAROVER,VARCCINT
* EOT
.dc.w 0
.even
*---------------------------------------------
* 演算子
*---------------------------------------------
* 文字列,0=両方,1=整数のみ,2=floatのみ
* 同じ文字列で始まる場合、長い物から先に記述する
ENmes:
?C0: .dc.b '(',0
?C1: .dc.b ')',0
?C2: .dc.b '++',0
?C3: .dc.b '--',0
?C5: .dc.b '==',0
?C6: .dc.b '>>>',1
?C7: .dc.b '<<<',1
?C8: .dc.b '>>',1
?C9: .dc.b '<<',1
?C10: .dc.b '>=',0
?C11: .dc.b '<=',0
?C12: .dc.b '>',0
?C13: .dc.b '<',0
?C14: .dc.b '!=',0
?C15: .dc.b '+',0
?C16: .dc.b '-',0
?C99: .dc.b '**',2 * べき乗(power)
?C17: .dc.b '*',0
?C18: .dc.b '/',0
?C98: .dc.b '&&',0
?C19: .dc.b '&',1
?C97: .dc.b '||',0
?C20: .dc.b '|',1
?C21: .dc.b '^',1
?C22: .dc.b '~',1
?C23: .dc.b '\',0
?C24: .dc.b '=',0
?C96: .dc.b '!',0
* 以下関数(べき乗だけは2項関数なので上の演算子にする)
* 英小文字
?ABS: .dc.b 'abs',2 * 絶対値
?CEIL: .dc.b 'ceil',2 * 小数切上
?FIX: .dc.b 'fix',2 * 整数部
?FLOOR: .dc.b 'floor',2 * 小数切捨
?FRAC: .dc.b 'frac',2 * 小数部
?SGN: .dc.b 'sgn',2 * 正負零
?EXP: .dc.b 'exp',2 * 指数関数
?SQR: .dc.b 'sqr',2 * 平方根
?PI: .dc.b 'pi',2 * 円周率乗算
?LOG10: .dc.b 'log10',2 * 常用対数
?LOG2: .dc.b 'log2',2 * 対数(底2)
?LOG: .dc.b 'log',2 * 自然対数
?SIN: .dc.b 'sin',2 * 正弦
?COS: .dc.b 'cos',2 * 余弦
?TAN: .dc.b 'tan',2 * 正接
?ATANH: .dc.b 'atanh',2 * 双曲逆正接
?ASIN: .dc.b 'asin',2 * 逆正弦
?ACOS: .dc.b 'acos',2 * 逆余弦
?ATAN: .dc.b 'atan',2 * 逆正接
?SINH: .dc.b 'sinh',2 * 正弦
?COSH: .dc.b 'cosh',2 * 双曲余弦
?TANH: .dc.b 'tanh',2 * 双曲正接
.even
*---------------------------------------------
* 演算子テーブル(上の演算子表と同じ順)
*---------------------------------------------
* 内部コード
enzansi:
.dc.w '(',')',VINC,VDEC,VEQU
.dc.w VRROT,VLROT,VRSHIFT,VLSHIFT
.dc.w VGE,VLE,'>','<',VNE,'+','-',VBEKI * べき乗
.dc.w '*','/',VAND,'&',VOR,'|','^','~','\','=','!'
* 以下関数
.dc.w __FABS,__FCEIL,__FFIX,__FFLOOR,__FFRAC
.dc.w __FSGN,__FEXP,__FSQR,__FNPI,__FLOG10
.dc.w __FLOG2,__FLOG,__FSIN,__FCOS,__FTAN
.dc.w __FATANH,__FASIN,__FACOS,__FATAN,__FSINH
.dc.w __FCOSH,__FTANH
*
.dc.w 0 * NULL = End of Table
*---------------------------------------------
* 演算子優先順位
*---------------------------------------------
Lvs_1:
.dc.w '=',0 * 代入
.dc.w VAND,VOR * 論理演算
.dc.w '&','|','^',0 * ビット演算(実数では不可)
.dc.w VEQU,VNE,'>','<',VGE,VLE,0 * 比較
.dc.w VRROT,VLROT,VRSHIFT,VLSHIFT,0 * ローテート、シフト(実数では不可)
.dc.w '+','-',0 * 加減
.dc.w '*','/','\',VBEKI,0 * 乗除剰余、べき乗(整数では不可)
.dc.w VDEC,VINC,VMINUS,'~','!',0 * 単項演算子('~'のみ実数では不可)
.dc.w $ffff * end of table
******************************************************************************
* サブルーチン
******************************************************************************
* 前に_のない関数は最適化済み
BREAKON:
* d0のみ破壊
move.w brksts(pc),-(sp) * BREAK mode
bra @f
BREAKOFF:
* d0のみ破壊
move.w #-1,-(sp) * read BREAK mode
DOS _BREAKCK
addq.w #2,sp
move.w d0,brksts
*
clr.w -(sp) * BREAK Cut
@@: DOS _BREAKCK
addq.w #2,sp
rts
*---------------------------------------------
ctol:
* long ctol(adrs)
* d0,a0破壊
move.l 4(sp),d0
move.l d0,a0
btst.l #0,d0
bne 1f
* 偶数アドレス = 直接読み出来る
move.l (a0),d0
rts
1: * 奇数アドレス = 直接読み出来ない
move.l 1(a0),d0 * 次のアドレスからH.L/L.H/L.L/DUMMYを読み取る
move.b (a0),d0
ror.l #8,d0
rts
*---------------------------------------------
check_kanji1:
* 漢字1バイト目判定
move.l 4(sp),d1
kcheck1:
moveq.l #0,d0
cmp.l #256,d1
bge nonkanji * 256以上は非漢字扱い
cmp.l #$80-1,d1 * 0x00~0x7fは漢字1バイト目でない
bls nonkanji
cmp.l #$a0-1,d1 * 0x80~0x9fは漢字1バイト目
bls kanji
cmp.l #$e0-1,d1 * 0xa0~0xdfは漢字1バイト目でない
bls nonkanji * 本当は0xfe,0xffは漢字1バイト目ではない
kanji:
moveq.l #1,d0
nonkanji:
tst.l d0 * 漢字かどうかの判定をフラグに反映しておく
rts
*---------------------------------------------
isalnum:
* 数字・アルファベット判定
move.b 4+3(sp),d1
isalnum2: * d1.b=code
moveq.l #1,d0 * for True
cmp.b #'0',d1
bcs 1f * <'0' : False
cmp.b #'9',d1
bls 2f * <='9' : True
cmp.b #'A',d1
bcs 1f * <'A' : False
cmp.b #'Z',d1
bls 2f * <='Z' : True
cmp.b #'a',d1
bcs 1f * <'a' : False
cmp.b #'z',d1
bls 2f * <='z' : True
1: moveq.l #0,d0 * False
2: rts
*---------------------------------------------
__FNEG2 macro dx
local L1
* 符号反転
tst.l dx
beq L1
bchg.l #31,dx
L1:
.endm
******************************************************************************
hash: * ハッシュ計算
* unsint hash(unchar *str)
* d0,d2,a0破壊
move.l 4(sp),a0 * str
moveq.l #0,d0 * h=0
moveq.l #0,d2 * c (for .b = .w)
@@: move.b (a0)+,d2
beq @f * EOS
mulu.w #7,d0 * d0.l=d0.w*7
add.w d2,d0
bra @b
*
@@: moveq.l #0,d2 * for .l = .w
move.w d0,d2 *
rts
*---------------------------------------------
make_base:
* 2/8/10/16進数文字列作成(整数のみ)
* 一番長くなるのは2進数で32ビット分=32バイト+符号
* base >0 : 正で処理 , base < 0 : 符号つきで処理
* int make_base(int code,unchar dec[2+BINT+1],int base)
ofs = (4*2)
regs .reg d3/d4
movem.l regs,-(sp)
move.l ofs+4(sp),d0 * num(unsigned)<-code
moveq.l #32+2,d3 * i
moveq.l #0,d2 * sign=0(.wでいい)
move.l ofs+12(sp),d1 * base<0?
bpl 1f * No
* base<0 : 符号付き
tst.l d0 * code<0?
bpl 2f * No
* code<0
neg.l d0 * num=-code
beq 2f * num==0? Yes
* num!=0
moveq.l #1,d2 * sign=1
2: neg.l d1 * base=-base
*
1: move.l ofs+8(sp),a0 * dec
lea (a0,d3.l),a0 * dec[i]
clr.b (a0) * =EOS
lea b(pc),a1 * b[]
3: cmp.l d1,d0 * num>=base?
bcs 4f * No
move.l d0,d4
FPACK __UMOD * d4.l=num%base d0%=d1(符号なし)
exg d0,d4
move.b (a1,d4.l),-(a0) * dec[--i]=b[num%base];
subq.l #1,d3 * --i
FPACK __UDIV * num/=base d0/=d1(符号なし)
bra 3b
*
4: move.b (a1,d0.l),-(a0) * dec[--i]=b[num]
subq.l #1,d3 * --i
tst.w d2 * sign==1?
beq @f * No
move.b #'-',-(a0) * 負号
subq.l #1,d3 * --i
@@: move.l d3,d0 * return(i)
movem.l (sp)+,regs
rts
*
b .dc.b '0123456789ABCDEF',0 * atoi3bでも使う
.even
*---------------------------------------------
atoi3b:
* int atoi3b(unchar *str,long *num,int base,unchar *(*after))
* 4 8 12 16
* base進数の文字列を数値に直す(実数対応):base=2~10,16
move.l 12(sp),d0 * base
cmp.l #10,d0 * 10進数?
bne @f * No : とりあえず読み取りはatoi3bに任せる
* 10進数
tst.b ffloat
beq @f * 整数
* 実数10進数読み取り
movem.l 4(sp),a0/a1 * str/*num
FPACK __STOF * -> d0.l
move.l d0,(a1) * -> *num
move.l 16(sp),a1
move.l a0,(a1) * *after=str
moveq.l #0,d0 * ret
rts
*
ofs = (4*3)
regs .reg d3-d5
@@: movem.l regs,-(sp)
moveq.l #0,d0 * v=0
moveq.l #0,d5 * ret=0
lea b(pc),a1 * 0~9,A~F
*
move.l ofs+12(sp),d1 * base
move.l ofs+4(sp),a0 * str
1: move.b (a0)+,d2 * c=*str++
beq 2f * EOS
cmp.b #'_',d2 * セパレーター
beq 1b * 飛ばす
* 数字変換
cmp.b #'a',d2
bcs @f * <'a'
and.b #%1101_1111,d2 * 大文字化
@@: moveq.l #-1,d3 * 数字
@@: addq.l #1,d3
move.b (a1,d3.l),d4 * b[数字]
beq atoi3_err * 数字文字列でない
cmp.b d4,d2
bne @b
cmp.l d1,d3 * 数字>=base?
bcc atoi3_err * Yes : base範囲でない
FPACK __LMUL * v*=base d0*=d1
add.l d3,d0 * v+=数字
bra 1b
*
atoi3_err:
moveq.l #-2,d5 * エラー
2: tst.b ffloat
beq @f * 整数
* 整数->実数変換
FPACK __LTOF * signed int → float ; d0 = d0
@@: move.l ofs+8(sp),a1 * *num
move.l d0,(a1) * *num=v
move.l ofs+16(sp),d4 * *after
beq @f * NULL
move.l d4,a1
subq.l #1,a0 * str-1
move.l a0,(a1) * *after=str-1
@@: move.l d5,d0 * ret
movem.l (sp)+,regs
rts
*---------------------------------------------
read_var_name:
* 変数名読みだし
* unchar *read_var_name(unchar *str,unchar vname[],int max)
* 4 8 12
movem.l 4(sp),a0/a1/a2 * str/vname/max
moveq.l #0,d2 * p=0
*
2: move.b (a0)+,d1 * c=*str++
beq 1f * EOS
cmp.l a2,d2 * p>=max?
bcs @f * NO
* over
moveq.l #0,d0 * return(NULL)
rts
*
@@: * 変数に使えない文字が出てきたら終わり
cmp.b #'_',d1
beq @f * '_'は大丈夫
bsr isalnum2 * d1.b -> d0.l
tst.l d0
beq 1f * アルファベット+数字でない
or.b #$20,d1 * 小文字化(ここに来るのは英数字のみなのでこれで良い)
@@: move.b d1,(a1)+ * vname[p]=c
addq.l #1,d2 * p++
bra 2b
*
1: subq.l #1,a0 * 使えない文字のところに合わせる
clr.b (a1) * vname[p]=0
* 変数名直後のアドレスを返す
move.l a0,d0 * str
rts
*---------------------------------------------
var_num_write:
* 変数に数値を書き込む
* long var_num_write(long point,long num,int mode)
* 4 8 12
movem.l 4(sp),d0/d1/d2 * point/num/mode
cmp.l #VTOP,d0
bcs @f * point<VTOP
lea var(pc),a1
cmp.l vwsize(a1),d0 * point>var.vwsize?
bls 1f * no
@@: * ポイントがおかしい
moveq.l #-2,d0
rts
*
1: move.l vwork(a1),a0 * vwork
lea (a0,d0.l),a0 * &vwork[point]
*
btst.l #15,d2 * 強制再定義モード?
bne @f * Yes -> 再代入不可にかかわらず代入する
*
btst.b #BVDAI,Vmd(a0) * vwork[point+1]&VDAI?
beq @f * No
* 再代入不可
moveq.l #-1,d0
rts
*
@@: move.b d2,Vmd(a0) * vwork[point+1]=mode
* *(long *)vwork[point+2]=num
lea Vnum(a0),a1
move.l a1,d2
btst.l #0,d2
bne @f
* 偶数アドレス = 直接書き込める
move.l d1,(a1)
bra 2f
*
@@: * 奇数アドレス ; 68020以降なら一発書き込みなんだけど
move.b d1,3(a1) * L.L
lsr.l #8,d1
move.w d1,1(a1) * H.L/L.H
swap d1
move.b d1,(a1) * H.H
*
2: moveq.l #0,d1 * for .b=.l
move.b (a0),d1 * vwork[point]
add.l d1,d0 * +point
addq.l #7,d0 * +6+1
rts
*---------------------------------------------
var_num_read:
* 変数数値・モード読みだし
* int var_num_read(long point,long *num)
* 4 8
movem.l 4(sp),d0/a2 * point/*num
cmp.l #VTOP,d0
bcs @f * point<VTOP
lea var(pc),a1
cmp.l vwsize(a1),d0 * point>var.vwsize?
bls 1f * no
@@: * ポイントがおかしい
moveq.l #VARAROVER,d0
rts
*
1: move.l vwork(a1),a0 * vwork
lea (a0,d0.l),a0 * &vwork[point]
move.b Vmd(a0),d0 * md=vwork[point+1]
move.b d0,d1 * md
and.b #VKAKU,d0
beq @f
* 未確定
moveq.l #VARNKAKU,d0
rts
*
@@: * 読みだし
pea Vnum(a0) * &vwork[point+2]
bsr ctol * -> d0.l(d0,a0破壊)
addq.l #4,sp
* 変数交互変換
and.b #VTYPE,d1 * 型取りだし
tst.b ffloat
beq @f * 整数モード
* 実数モードにいる
tst.b d1
bne 1f * 実数変数である=そのまま
* 整数変数を実数で読み取る
FPACK __LTOF * signed int → float ; d0 = d0
bra 1f
*
@@: * 整数モード
tst.b d1
beq 1f * 整数変数である=そのまま
* 実数変数を整数で読み取る
FPACK __FTOL * float → signed int ; d0 = d0
bcc 1f
* 整数化出来ない
moveq.l #VARCCINT,d0
rts
*
1: move.l d0,(a2) * -> *num
moveq.l #0,d0 * return(0)
rts
*---------------------------------------------
var_search:
* long var_search(unchar *vname)
* 変数サーチ
* return=0:その変数は定義されていない
* >0:その変数の格納位置(数値確定)
* <0:その変数の格納位置*-1(数値未確定)
ofs= (4*3)
regs .reg d3/d6/a3
movem.l regs,-(sp)
lea var(pc),a1
cmp.l #VTOP,vpoint(a1) * vpoint==VTOP?
beq vsNone * Yes : 変数が1つもない
*
* ハッシュで最初のサーチポイントを決める
* p=vhash[hash(vname)%vhsize];
move.l 4+ofs(sp),a3 * vname
pea (a3)
bsr hash * a0,d0,d2破壊 -> d0.l=d0.w
addq.l #4,sp
*
lea var(pc),a1
divu.w vhsize(a1),d0 * d0.l.w=d0.l/vhsize.w ... d0.h.w
clr.w d0 * for .w = .l ; 答部分を消す
swap d0 * 余り(=d0.l)
add.l d0,d0
add.l d0,d0 * *4 for long
move.l vhash(a1),a0 * vhash
move.l (a0,d0.l),d6 * p=vhash[...]
*
bclr.l #31,d6 * p&BIT31?
sne.b d3 * Yes -> fdbl=1/BIT31=0
moveq.l #1,d0
and.l d0,d3 * fdbl=0/1
tst.l d6
bls vsNone * p<=0
* p>0 ; ハッシュにはあった
* len=strlen(vname) ; 変数名長
moveq.l #-1,d2 * len=-1
@@: addq.w #1,d2 * len++
tst.b (a3)+
bne @b
*
move.l vwork(a1),a3 * vwork
move.l vpoint(a1),d0 * vpoint
lea (a3,d0.l),a2 * &vwork[vpoint]
add.l d6,a3 * &vwork[p]
* d3.w=fdbl,d1.w=vlen,d2.w=len,d6.l=p,a1=var,a3=vname/&vwork[p],a2=&vwork[vpoint]
vsloop: * 格納エリアからサーチ
* 比較
moveq.l #0,d1 * for .b = .w = .l
move.b (a3),d1 * vlen=var.vwork[p]
cmp.w d1,d2 * vlen==len? 変数名長も一致?
bne 4f * No
* 変数名比較
lea Vname(a3),a0 * vwork[p+6]
move.l 4+ofs(sp),a1 * vname
move.w d1,d0 * vlen
subq.w #1,d0 * -1 for dbra
@@: cmp.b (a0)+,(a1)+ * vwork <-> vname
dbne d0,@b
bne 4f * 不一致で終わった時
* 一致で終わった
move.l d6,d0 * p
move.b Vmd(a3),d1 * m=vwork[p+1] ; モード・型
and.b #VKAKU,d1 * m&VKAKU
beq vsRet * p : 確定
neg.l d0 * -p: 未確定
bra vsRet * return(m&VKAKU? -p:p) ; 未確定:確定
*
4: * 変数名長が一致しない時は即不一致
tst.w d3 * fdbl?
beq vsNone * Yes : ハッシュ重複無し:ここで一致しなければ無し
* 次の変数へ
add.l d1,d6 * p+vlen
addq.l #sizeV+1,d6 * p+(6+1)
lea sizeV+1(a3,d1.l),a3 * &vwork[p]
cmp.l a2,a3 * &vwork[p]<&vwork[vpoint]?
bcs vsloop * Yes
vsNone: * ハッシュにない/この変数は登録されていない/変数が全く無い
moveq.l #0,d0
vsRet: movem.l (sp)+,regs
rts
*---------------------------------------------
var_hash_set:
* ハッシュ登録
* int var_hash_set(unchar *vname)
move.l 4(sp),-(sp)
bsr hash * h=d0.l(=.w)
addq.l #4,sp
*
lea var(pc),a0
divu.w vhsize(a0),d0 * hash%var.vhsize ; d1.h.w=余り
clr.w d0 * for .w = .l
swap d0 * h=d0.l.w=d0.l
add.l d0,d0
add.l d0,d0 * *4
move.l vhash(a0),a1 * vhash
lea (a1,d0.l),a1 * vhash[h]
tst.l (a1) * すでにそのハッシュは使われている?
beq @f * No
* 使われている
* bset.l #31,(a1) * |BIT31 = 重複フラグ
bset.b #7,(a1) * 上と同意になる
moveq.l #1,d0 * return(1)
rts
*
@@: move.l vpoint(a0),(a1) * var.vhash[h]=var.vpoint
moveq.l #0,d0 * return(0)
rts * 登録完了
*---------------------------------------------
var_define:
* long var_define(unchar *vname,int mode)
* 変数登録(仮確定)
* mode : VDAI=0:普通/1:再代入不可 , VTYPEも指定可能
ofs = (4*4)
regs .reg d3-d5/a3
movem.l regs,-(sp)
* d3.l=p,d4.l=p0,d5.w=len,a3=vname
move.l 4+ofs(sp),a3 * vname
pea (a3)
bsr var_search * 新規登録/変更判定
addq.l #4,sp
tst.l d0
beq @f
* p!=0 : 2重定義
moveq.l #-2,d0
bra vdRet
*
@@: * len=strlen(vname) ; 変数名長
move.l a3,a0
moveq.l #-1,d5 * len=-1
@@: addq.l #1,d5 * len++
tst.b (a0)+
bne @b * .b=.w=.l
cmp.w vlmax(a1),d5 * len>vlmax?
bls @f * No(<=)
* Yes : 変数名長が長すぎる
moveq.l #-3,d0
bra vdRet
*
@@: * 変数は未定義 -> 新規登録:最初は必ず数値未確定
lea var(pc),a1
move.l vpoint(a1),d3 * p =vpoint
move.l d3,d4 * p0=vpoint
move.l d3,d0 * p
addq.l #sizeV+1,d0 * 1+1+LLONG+1
add.l d5,d0
cmp.l vwsize(a1),d0 * p+1+1+LLONG+len+1>=vwsize?
bcs @f * No(<)
* これ以上格納できない
moveq.l #-1,d0
bra vdRet
*
@@: * ハッシュ設定
pea (a3) * vname
bsr var_hash_set
addq.l #4,sp
*
* 変数格納
lea var(pc),a1
move.l vwork(a1),a2 * vwork
add.l d3,a2 * &vwork[p]
*
move.b d5,(a2)+ * vwork[p++]=(unchar)len ; 変数名長
move.b 3+8+ofs(sp),(a2)+ * vwork[p++]=(unchar)mode ; TYPE
* 0/0.0で仮確定
* 4バイトにデータを書き込むが、奇数バイト境界もあるので1バイトごと書いている
clr.b (a2)+ * 整数も実数も0は0
clr.b (a2)+
clr.b (a2)+
clr.b (a2)+ * vwork[p+=LLONG]=0/0.0
@@: move.b (a3)+,(a2)+ * strcpy(&vwork[p],vname) ; 変数名格納
bne @b
addq.l #sizeV+1,d3 * p+1+1+LLONG+1
add.l d5,d3 * +len
move.l d3,vpoint(a1) * vpoint=次の書きこみ位置
* 変数個数
addq.l #1,vlots(a1) * vlots++;
move.l d4,d0 * return(p0) ; この変数の先頭アドレスを返す
vdRet: movem.l (sp)+,regs
rts
*---------------------------------------------
var_read2:
* 変数読みだし
* int var_read2(unchar *vname,long *num,long *pp)
* 4 8 12
* return : 0=読み出せた , VARNKAKU/VARNDEF/VARAROVER/VARCCINT=エラー
move.l 4(sp),-(sp)
bsr var_search * p
addq.l #4,sp
tst.l d0 * p=0?
bne @f * NO
* 変数は未定義(p=0)
moveq.l #VARNDEF,d0
rts
*
@@: move.l 12(sp),a0
move.l d0,(a0) * *pp=p
bge @f * >=0
* 変数が未確定(p<0)
moveq.l #VARNKAKU,d0
rts
*
@@: * 読みだし
move.l 8(sp),-(sp) * num
move.l d0,-(sp) * p
bsr var_num_read
addq.l #8,sp
rts
*---------------------------------------------
_NumVarRead:
link a6,#0
movem.l d3/d4/d5/d6/a3/a4/a5,-(sp)
move.l 12(a6),a5
move.l 16(a6),a4
move.l 20(a6),a3
moveq.l #10,d1
moveq.l #0,d5
moveq.l #22,d2
add.l #var,d2
move.l d2,a0
move.l d5,d0
move.w (a0),d0
addq.l #2,d0
moveq.l #-2,d2
and.l d2,d0
sub.l d0,sp
move.l sp,d4
jbne N124
moveq.l #55,d2
move.l d2,(a3)
move.l d5,d0
jbra N123
N124:
moveq.l #0,d2
move.l d2,(a4)
move.l 8(a6),d6
move.l d2,(a3)
move.l 8(a6),a0
cmp.b #45,(a0)
jbne N125
moveq.l #1,d5
addq.w #1,a0
move.l a0,8(a6)
N125:
move.l 8(a6),a0
moveq.l #0,d0
move.b (a0),d0
moveq.l #-36,d2
add.l d2,d0
moveq.l #28,d2
cmp.l d2,d0
jbhi N126
add.l d0,d0
NI133:
move.w N133-NI133-2(pc,d0.l),d2
jmp 2(pc,d2.w)
N133:
.dc.w N132-N133
.dc.w N130-N133
.dc.w N126-N133
.dc.w N127-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N126-N133
.dc.w N131-N133
N127:
move.l 8(a6),a0
addq.w #1,a0
move.l a0,8(a6)
clr.w d3
move.b (a0)+,d3
move.l a0,8(a6)
moveq.l #0,d0
move.w d3,d0
move.l d0,-(sp)
jbsr check_kanji1
tst.l d0
jbeq N128
move.w d3,d0
lsl.w #8,d0
move.l 8(a6),a0
clr.w d1
move.b (a0)+,d1
move.w d0,d3
or.w d1,d3
move.l a0,8(a6)
N128:
move.l 8(a6),a0
move.b (a0)+,d0
move.l a0,8(a6)
cmp.b #39,d0
jbeq N129
moveq.l #14,d2
jbra N152
N129:
moveq.l #0,d0
move.w d3,d0
move.l d0,(a5)
jbra N151
N130:
moveq.l #2,d1
jbra N126
N131:
moveq.l #8,d1
jbra N126
N132:
moveq.l #16,d1
N126:
moveq.l #10,d2
cmp.l d1,d2
jbne N135
move.l 8(a6),a0
clr.w d3
move.b (a0),d3
cmp.w #47,d3
jbls N137
cmp.w #57,d3
jbls N149
N137:
moveq.l #0,d0
move.w d3,d0
move.l d0,-(sp)
jbsr isalnum
addq.w #4,sp
tst.l d0
jbne N138
cmp.w #95,d3
jbeq N138
moveq.l #58,d2
jbra N152
N138:
moveq.l #22,d2
add.l #var,d2
move.l d2,a0
moveq.l #0,d0
move.w (a0),d0
move.l d0,-(sp)
move.l d4,-(sp)
move.l 8(a6),-(sp)
jbsr read_var_name
move.l d0,8(a6)
lea 12(sp),sp
jbne N139
moveq.l #53,d2
jbra N152
N139:
move.l a4,-(sp)
move.l a5,-(sp)
move.l d4,-(sp)
jbsr var_read2
move.l d0,d3
lea 12(sp),sp
moveq.l #50,d2
cmp.l d3,d2
jbne N140
tst.b ftei
beq @f
pea (0|VDAI).w * 定数モード
bra 1f
@@: pea 0.w * 普通モード
1: move.l d4,-(sp)
jbsr var_define
move.l d0,(a4)
jbge N141
moveq.l #-2,d2
cmp.l d0,d2
jbeq N144
moveq.l #-1,d2
cmp.l d0,d2
jbne N155
moveq.l #54,d2
jbra N153
N144:
moveq.l #57,d2
N153:
move.l d2,(a3)
jbra N155
N141:
neg.l (a4)
bra N148
N140:
tst.l d3
jbeq N148
move.l d3,(a3)
N155:
moveq.l #0,d0
jbra N123
N135:
addq.l #1,8(a6)
addq.l #1,d6
N149:
pea 8(a6)
move.l d1,-(sp)
move.l a5,-(sp)
move.l 8(a6),-(sp)
jbsr atoi3b
N148:
cmp.l 8(a6),d6
jbne N150
moveq.l #1,d2
N152:
move.l d2,(a3)
jbra N155
N150:
tst.l d5
jbeq N151
*
tst.b ffloat
beq @f * 整数
* float符号反転
move.l (a5),d0
__FNEG2 d0 * floatでは負号処理が変わる
move.l d0,(a5)
bra N151
*
@@: * 整数符号反転
neg.l (a5)
N151:
move.l 8(a6),d0
N123:
movem.l -28(a6),d3/d4/d5/d6/a3/a4/a5
unlk a6
rts
*---------------------------------------------
* 関数実行
* プログラムを書き替えるため、キャッシュクリアが必要
func: .dc.w FeMin * ここが書き変わる
rts
*---------------------------------------------
Enzan:
* int Enzan(void)
* 演算&符号処理(代入は外部のfuncで処理)
* スタック上の処理だけ
* return : d0.l : >0:演算子 , <0:エラー(d1.l=エラーコード)
* d1=v2,d2=v1,d3=e,d4=vs,a1=Vsikis,a2=Vsikis.vstack[vs],d0/d5/a0=汎用
ofs = (4*3)
regs .reg d3-d5
movem.l regs,-(sp)
lea Vsikis(pc),a1
move.w vs(a1),d4 * vs
beq Eill * vs==0 -> エラー(無いはずだけど)
* 第2項取り出し
* v2=vstack[--vs]
subq.w #1,d4 * --vs
move.w d4,vs(a1) * 記録
move.l vstack(a1),a0 * vstack
moveq.l #0,d0 * for .w -> .l
move.w d4,d0
add.l d0,d0
add.l d0,d0 * *4 for long
lea.l (a0,d0.l),a2 * vstack[vs]
move.l (a2),d1 * v2
* 演算子取り出し
* e=Vsikis.estack[--Vsikis.es];
move.l estack(a1),a0 * estack
moveq.l #0,d0 * for .w -> .l
move.w es(a1),d0 * es
subq.w #1,d0 * --es
move.w d0,es(a1) * 記録
add.l d0,d0 * *2 for unsint
move.w (a0,d0.l),d3 * e
*
* 単項演算子
lea E1tableI(pc),a0 * 整数
tst.b ffloat
beq @f
cmp.w #FeMin,d3
bcc Func * >=FeMin;演算子である
lea E1tableF(pc),a0 * float
@@: move.l (a0)+,d5 * jump|code
beq kou2 * -> end of table
cmp.w d3,d5 * =code?
bne @b * no
swap d5 * d5=jump
move.l d1,d0 * いろいろと使うので;d0=v2
jsr -4(a0,d5.w) * 単項演算子であった
70: * <- ここに帰ってくる
move.l d1,(a2) * vstack[vs]=v2
addq.w #1,d4 * vs++
move.w d4,vs(a1) * 保存
Eok: moveq.l #0,d0 * for .w = .l
move.w d3,d0 * return(e)
Eret: movem.l (sp)+,regs
rts
*
Eill: * 式エラー(これはメインで起こる)
moveq.l #VSILL,d1
moveq.l #-1,d0
bra Eret
*
* 以下は各演算子で起こる
Eover2: * オーバー/アンダー
bvs Eover * V=0:アンダー,V=1:オーバー
Eunder: * アンダーフロー
moveq.l #VSUNDER,d1
bra Eerr
*
Eover: * オーバーフロー
moveq.l #VSOVER,d1
Eerr: moveq.l #-1,d0 * エラーの印
add.l #4,sp * jsrの戻りアドレスを消す
bra Eret
Ediv2: * オーバー/アンダー/0除算
bne Eover2 * Z=0:over/under,Z=1:0除算
* Z=1:0除算
Ediv0: * 0除算
moveq.l #VS0DIV,d1
bra Eerr
*
*
Func: * 関数実行;関数は単項演算子である(float)
* プログラム内部を書き替えるためキャッシュをoffしてから実行する
* 自己書き替え
move.w d3,func * eがfeファンクションコールそのものである
* キャッシュクリア
move.b $e8e00b,d0 * bit7-4:CPU type
cmp.b #%1111_0000,d0
bcc @f * =68000
* 68020以降機
movem.l d1-d2,-(sp)
moveq.l #1,d1 * キャッシュ状態読み出し
IOCS _SYS_STAT
move.l d1,-(sp) * 保存
moveq.l #0,d2 * キャッシュoff
moveq.l #4,d1 * キャッシュのセット(d2.l)
IOCS _SYS_STAT
* キャッシュ戻し
move.l (sp)+,d2 * 前のキャッシュ状態
moveq.l #4,d1 * キャッシュのセット(d2.l)
IOCS _SYS_STAT * キャッシュ状態を設定
movem.l (sp)+,d1-d2
@@: *
move.l d1,d0 * v2
bsr func * 関数実行($fexx);全て単項演算子 v2=func(v2)
bcs Eover3 * エラーチェック
move.l d0,d1 * v2
bra 70b
*
Eover3: * オーバー/アンダー/引数おかしい
subq.l #4,sp * 後でadd.l #4,spがあるのでそれをスキップさせるため(フラグ不変)
bvs Eover2
* bne Eover2 * Z=0:over/under,Z=1:引数おかしい
* 引数エラー
moveq.l #VSARG,d1
bra Eerr
*
* テーブルは良く出てくる順に並べる
E1tableI: * 整数1項演算子テーブル
.dc.w EminusI-$,VMINUS * 負号
.dc.w EbnotI-$,'~' * ビットNOT
.dc.w EincI-$,VINC * ++
.dc.w EdecI-$,VDEC * --
.dc.w EnotI-$,'!' * 論理NOT
.dc.w 0,0
*
E1tableF: * 実数1項演算子テーブル
.dc.w EminusF-$,VMINUS * 負号
.dc.w EincF-$,VINC * ++
.dc.w EdecF-$,VDEC * --
.dc.w EnotF-$,'!' * 論理NOT
.dc.w 0,0
*
**** 整数
EminusI:
neg.l d1 * v2=-v2
rts
EbnotI:
not.l d1 * v2=~v2
rts
EincI:
addq.l #1,d1 * v2++(オーバーフローチェックなし)
rts
EdecI:
subq.l #1,d1 * v2--(アンダーフローチェックなし)
rts
EnotI:
tst.l d1
seq d1 * 0->1,!=0->0
moveq.l #1,d0
and.l d0,d1 * 0/1
rts
*
**** 実数
EminusF:
__FNEG2 d1 * 負号
rts
EincF:
FPACK __FADDONE * v2++
bra @f
EdecF:
FPACK __FSUBONE * v2--
@@: bcs Eover2
move.l d0,d1
rts
EnotF:
FPACK __FTST * v1==0?
seq d0 * 0->1,!=0->0
moveq.l #1,d1
and.l d1,d0 * 0/1
FPACK __LTOF * signed int → float ; d0 = d0
move.l d0,d1
rts
*
*
kou2: * 2項演算子
* if (Vsikis.vs==0) return(-1); /* error : 第1項がない */
tst.w d4 * vs==0?
beq Eill * Yes
* 第1項取り出し
move.l -4(a2),d2 * v1=vstack[vs-1]
* 2項演算
lea E2tableI(pc),a0 * 整数
tst.b ffloat
beq @f
* 実数
lea E2tableF(pc),a0 * 実数
@@: move.l (a0)+,d5 * jump|code
beq @f * -> end of table
cmp.w d3,d5 * =code?
bne @b * no
swap d5 * d5=jump
move.l d2,d0 * いろいろと使うので
jsr -4(a0,d5.w)
@@: * <- ここに帰ってくる
move.l d2,-4(a2) * vstack[vs-1]=v1
bra Eok
*
*
E2tableI: * 整数2項演算子テーブル
.dc.w Edainyu2-$,'='
.dc.w Eplus2I-$,'+'
.dc.w Eminus2I-$,'-'
.dc.w Emul2I-$,'*'
.dc.w Ediv2I-$,'/'
.dc.w Emod2I-$,'\'
.dc.w Eband2I-$,'&'
.dc.w Ebor2I-$,'|'
.dc.w Ebxor2I-$,'^'
.dc.w Ershift2I-$,VRSHIFT
.dc.w Elshift2I-$,VLSHIFT
.dc.w Errot2I-$,VRROT
.dc.w Elrot2I-$,VLROT
.dc.w Eand2I-$,VAND
.dc.w Eor2I-$,VOR
.dc.w Egt2I-$,'>'
.dc.w Elt2I-$,'<'
.dc.w Eequ2I-$,VEQU
.dc.w Ene2I-$,VNE
.dc.w Ege2I-$,VGE
.dc.w Ele2I-$,VLE
.dc.w 0,0
*
E2tableF: * 実数2項演算子テーブル
.dc.w Edainyu2-$,'='
.dc.w Eplus2F-$,'+'
.dc.w Eminus2F-$,'-'
.dc.w Emul2F-$,'*'
.dc.w Ediv2F-$,'/'
.dc.w Emod2F-$,'\'
.dc.w Eand2F-$,VAND
.dc.w Eor2F-$,VOR
.dc.w Egt2F-$,'>'
.dc.w Elt2F-$,'<'
.dc.w Eequ2F-$,VEQU
.dc.w Ene2F-$,VNE
.dc.w Ege2F-$,VGE
.dc.w Ele2F-$,VLE
.dc.w Epower2F-$,VBEKI
.dc.w 0,0
*
**** 整数・実数両用
Edainyu2:
movem.l d1-d2,-(sp)
move.l d1,-(sp) * v2
bsr Dainyu
addq.l #4,sp
movem.l (sp)+,d1-d2
tst.l d0
bne @f
move.l d1,d2 * v1=v2
rts
@@: * funcのエラー
move.l d0,d1 * Dainyuの返すエラーコード
bra Eerr
*
**** 整数
Eplus2I:
add.l d1,d2 *(オーバーフローチェックなし)
rts
Eminus2I:
sub.l d1,d2 *(アンダーフローチェックなし)
rts
Eband2I:
and.l d1,d2
rts
Ebor2I:
or.l d1,d2
rts
Ebxor2I:
eor.l d1,d2
rts
Ershift2I:
lsr.l d1,d2
rts
Elshift2I:
lsl.l d1,d2
rts
Errot2I:
ror.l d1,d2
rts
Elrot2I:
rol.l d1,d2
rts
Egt2I:
cmp.l d1,d2
sgt d2
bra E0
Elt2I:
cmp.l d1,d2
slt d2
bra E0
Eequ2I:
cmp.l d1,d2
seq d2
bra E0
Ene2I:
cmp.l d1,d2
sne d2
bra E0
Ege2I:
cmp.l d1,d2
sge d2
bra E0
Ele2I:
cmp.l d1,d2
sle d2
E0: moveq.l #1,d0
and.l d0,d2
rts
Eand2I:
and.l d1,d2
sne d2
bra E0
Eor2I:
or.l d1,d2
sne d2
bra E0
Emul2I:
* 64bitで演算させ、下位32ビットを取る
* このため、オーバーフローが出ない
FPACK __IMUL * d0d1=v1(d0)*v2(d1)
move.l d1,d2 * v1=
rts
Ediv2I:
FPACK __LDIV * d0=v1(d0)/v2(d1)
bcs Ediv0 * C=1 ; 0除算
move.l d0,d2 * v1=
rts
Emod2I:
FPACK __LMOD * d0=v1(d0)%d1(d1)
bcs Ediv0 * C=1 ; 0除算
move.l d0,d2 * v1=
rts
*
**** 実数
Eplus2F:
FPACK __FADD * v2+v1(順序関係なし)
bcs Eover2
move.l d0,d2
rts
Eminus2F:
FPACK __FADD * v1-v2
bcs Eover2
move.l d0,d2
rts
Emul2F:
FPACK __FMUL * d0=d0*d1(順序関係なし)
bcs Eover2
move.l d0,d2
rts
Ediv2F:
FPACK __FDIV * d0=d0/d1
bcs Ediv2 * C=1 ; 0除算
move.l d0,d2
rts
Emod2F:
FPACK __FMOD * d0=d0%d1
bcs Ediv2 * C=1 ; 0除算
move.l d0,d2
rts
Epower2F:
FPACK __FPOWER * power(d0,d1)
bcs Eover2
move.l d0,d2
rts
*
Egt2F:
FPACK __FCMP * float 比較
sgt d2
bra E1
Elt2F:
FPACK __FCMP * float 比較
slt d2
bra E1
Eequ2F:
FPACK __FCMP * float 比較
seq d2
bra E1
Ene2F:
FPACK __FCMP * float 比較
sne d2
bra E1
Ege2F:
FPACK __FCMP * float 比較
sge d2
bra E1
Ele2F:
FPACK __FCMP * float 比較
sle d2
E1: moveq.l #1,d0
and.l d2,d0
FPACK __LTOF * signed int → float ; d0 = d0
move.l d0,d2
rts
AndOrF:
FPACK __FTST * v1==0?
sne d2
move.l d1,d0
FPACK __FTST * v2==0?
sne d1
rts
Eand2F:
bsr AndOrF
and.b d1,d2
sne d2
bra E1
Eor2F:
bsr AndOrF
or.b d1,d2
sne d2
bra E1
*---------------------------------------------
EnzanRead:
* 演算子&括弧読み取り
* unchar *EnzanRead(unchar *str,unsint *no)
* 数字や>=0x7fの演算子はない
lea ENmes(pc),a2 * 演算子名表
move.l 4(sp),a1 * str
move.b (a1),d0 * c=*str ; 1文字目
cmp.b #'0',d0
bcs @f * <'0'
* >='0'
cmp.b #'9',d0
bls ERret * <='9' : 0~9は演算子としてありえない
cmp.b #$7f,d0
bcc ERret * >=$7f : ここの部分も演算子としてありえない
*
@@: lea enzansi(pc),a0 * code.w
2: move.w (a0)+,d0 * code
beq ERret * NULL(end of table) -> return(NULL)
move.l 4(sp),a1 * s=str
4: cmp.b #2,(a2) * *e<=2?
bls 3f * Yes : 一致
move.b (a1)+,d1 * *s
cmp.b #'Z',d1 * >'Z'
bhi @f
cmp.b #'A',d1 * <'A'
bcs @f
* 英大文字のみ
or.b #$20,d1 * 小文字化
@@: cmp.b (a2)+,d1
beq 4b
* 次の演算子
@@: cmp.b #2,(a2)+
bhi @b * (a2)>2
bra 2b
*
3: * 一致
move.b (a2),ifflag * 演算子有効範囲
move.l 8(sp),a2 * *no
move.w d0,(a2) * *no=code
move.l a1,d0 * return(s)
1: *
rts
ERret: moveq.l #0,d0 * return(NULL)
rts
*---------------------------------------------
Yusen:
* 演算子優先順位:順位が高いものほど数字が大きい
* int Yusen(unint c)
move.w 4+2(sp),d2
* float用関数は全て特別優先順位
cmp.w #FeMin,d2 * >=$fexx?
bcs @f * No
moveq.l #65,d0 * 優先順位65(乗除剰余の上、単項演算子の下)
rts
*
@@: lea Lvs_1(pc),a0
moveq.l #10,d0 * lv=10
@@: move.w (a0)+,d1 * cc
cmp.w #$ffff,d1
beq 1f * end of table
cmp.w d2,d1 * 演算子内部コード一致?
beq 2f * 見つかった
tst.w d1 * cc==0?
bne @b * No
* =0
add.l #10,d0 * lv+=10
bra @b
*
1: * 見つからない
moveq.l #0,d0
2: rts
*---------------------------------------------
Dainyu:
* 変数への代入処理
* int Dainyu(long v2)
* return : 0=ok , <>0=VS*エラーコード
lea Vsikis(pc),a0
moveq.l #0,d0 * for .w = .l
move.w vs(a0),d0 * vs
subq.l #1,d0 * vs-1
add.l d0,d0
add.l d0,d0 * *4
move.l pstack(a0),a1 * pstack
move.l (a1,d0.l),d0 * p=pstack[vs-1]
beq 4f * p=0 : error
bpl @f * p>=0
* p<0 : 未確定変数
neg.l d0 * p=-p; 未確定->確定代入
@@: * ここでは数値代入しかできない
* if (var_num_write(p,v2,0/*0=整数,1=単精度実数*/)<0) return(-2);
tst.b ffloat
sne.b d2
moveq.l #1,d1
and.l d1,d2 * 整数=0,実数=1
tst.b ftei
beq @f
* 定数定義モード(初期式ファイル)
or.l #BIT15|VDAI,d2 * 強制再定義&再定義不可モード
@@: move.l 4(sp),d1 * v2
movem.l d0/d1/d2,-(sp)
* move.l d2,-(sp) * VTYPE=0/1,BIT15
* move.l d1,-(sp) * v2
* move.l d0,-(sp) * p
bsr var_num_write
lea 4*3(sp),sp
tst.l d0
bmi 2f * 再代入不可
moveq.l #0,d0 * return(0)
rts
2: * 再代入不可ならエラー
moveq.l #VARCSTA,d0
rts
4: * p=0 : 数値に代入しようとした
moveq.l #VSNUMST,d0
rts
*---------------------------------------------
_vsiki:
link a6,#-30
movem.l d3/d4/d5/d6/d7/a3/a4/a5,-(sp)
moveq.l #0,d2
move.l d2,-14(a6)
clr.w d5
move.w d5,d6
moveq.l #1,d4
lea Vsikis(pc),a0
move.w d5,es(a0)
move.w d5,vs(a0)
move.l 8(a6),a1
move.l (a1),a5
move.l #Vsikis,d7
move.l d7,d2
addq.l #6,d2
move.l d2,-22(a6)
move.l d7,a4
addq.w #4,a4
move.l d7,d2
addq.l #8,d2
move.l d2,-26(a6)
move.l d7,d2
addq.l #2,d2
move.l d2,-30(a6)
jbra ?228
?263:
cmp.b #32,d3
jbeq ?232
cmp.b #9,d3
jbne ?231
?232:
addq.w #1,a5
jbra ?228
?231:
pea -2(a6)
move.l a5,-(sp)
jbsr EnzanRead
move.l d0,d1
addq.w #8,sp
jbeq ?233 * NULL
* float
move.b ifflag(pc),d0
tst.b ffloat
beq @f
* 実数時
tst.b d0 * 両方使える演算子?
beq 10f * Yes
cmp.b #2,d0 * 実数で使える演算子?
beq 10f * Yes
moveq.l #VSIONLY,d0 * 整数時しか使えない
bra ?227 * error
*
@@: * 整数時
cmp.b #1,d0
bls 10f * <=1は大丈夫
* ifflag=2 ; floatのみの関数である
moveq.l #VSFONLY,d0 * float時しか使えない
bra ?227 * error
*
10: move.l d1,a5
move.w -2(a6),d1
moveq.l #0,d0
move.w d1,d0
moveq.l #40,d2
cmp.l d0,d2
jbeq ?249
moveq.l #41,d2
cmp.l d0,d2
jbeq ?252
tst.l -14(a6)
jbge ?236
cmp.w #61,d1
jbeq ?236
moveq.l #52,d0
jbra ?227
?236:
clr.w d5
move.w d5,d6
tst.w d4
jbeq ?237
cmp.w #45,-2(a6)
jbne ?238
move.w #64,-2(a6)
?238:
cmp.w #43,-2(a6)
jbne ?237
clr.w d4
jbra ?228
?237:
move.l -22(a6),a1
tst.w (a1)
jbne ?240
move.w -2(a6),d0
cmp.w #64,d0 * @=VMINUS
jbeq ?240
cmp.w #33,d0 * '!'
jbeq ?240
cmp.w #126,d0 * '~'
jbeq ?240
cmp.w #65023,d0 * 関数;$fe00
jbhi ?240
moveq.l #3,d0
jbra ?227
?240:
tst.w (a4)
jble ?241
move.w -2(a6),d4
jbra ?242
?245:
moveq.l #0,d0
move.w d4,d0
move.l d0,-(sp)
lea Yusen(pc),a3
jbsr (a3)
move.l d0,d3
move.w (a4),d0
ext.l d0
add.l d0,d0
move.l d0,a0
move.l -26(a6),a1
add.l (a1),a0
moveq.l #0,d0
move.w -2(a0),d0
move.l d0,-(sp)
jbsr (a3)
addq.w #8,sp
cmp.l d3,d0
jblt ?241
cmp.w #61,d4
jbeq ?241
jbsr Enzan
move.l d1,-6(a6) * err
tst.l d0
jblt ?268
move.w d0,d4
?242:
tst.w (a4)
jbgt ?245
?241:
move.l d7,a1
move.w (a1),d2
cmp.w (a4),d2
jbne ?246
moveq.l #6,d0
jbra ?227
?246:
move.w (a4),d0
ext.l d0
move.l -26(a6),a1
move.l (a1),a0
add.l d0,d0
move.w -2(a6),(a0,d0.l)
addq.w #1,(a4)
cmp.w #64,-2(a6)
jbne ?247
clr.w d0
jbra ?248
?247:
moveq.l #2,d0
?248:
move.w d0,d4
moveq.l #0,d2
move.l d2,-14(a6)
jbra ?228
?249:
cmp.w #1,d6
jbne ?250
moveq.l #9,d0
jbra ?227
?250:
move.l d7,a1
move.w (a1),d2
cmp.w (a4),d2
jbne ?251
moveq.l #7,d0
jbra ?227
?251:
move.w (a4),d0
ext.l d0
move.l -26(a6),a1
move.l (a1),a0
add.l d0,d0
move.w -2(a6),(a0,d0.l)
addq.w #1,(a4)
clr.w d6
moveq.l #1,d5
moveq.l #3,d4
jbra ?228
?252:
cmp.w #1,d5
jbne ?254
moveq.l #10,d0
jbra ?227
?258:
jbsr Enzan
move.l d1,-6(a6) * err
tst.l d0
jblt ?268
tst.w (a4)
jbne ?254
moveq.l #8,d0
jbra ?227
?254:
move.w (a4),d0
ext.l d0
add.l d0,d0
move.l d0,a0
move.l -26(a6),a1
add.l (a1),a0
cmp.w #40,-2(a0)
jbne ?258
subq.w #1,(a4)
clr.w d5
move.w d5,d4
move.w d5,d6
jbra ?228
?233:
cmp.w #1,d6
jbne ?260
moveq.l #2,d0
jbra ?227
?260:
move.l -30(a6),a1
move.w (a1),d2
move.l -22(a6),a1
cmp.w (a1),d2
jbne ?261
moveq.l #5,d0
jbra ?227
?261:
pea -18(a6)
pea -14(a6)
pea -10(a6)
move.l a5,-(sp)
jbsr _NumVarRead
move.l d0,d1
lea 16(sp),sp
jbne ?262
move.l -18(a6),d0
jbra ?227
?262:
move.l -22(a6),a1
move.w (a1),d0
ext.l d0
move.l d7,a1
move.l 16(a1),a0
asl.l #2,d0
move.l -14(a6),(a0,d0.l)
move.l -22(a6),a1
move.w (a1),d0
ext.l d0
move.l d7,a1
move.l 12(a1),a0
asl.l #2,d0
move.l -10(a6),(a0,d0.l)
move.l -22(a6),a1
addq.w #1,(a1)
moveq.l #1,d6
clr.w d5
move.w d5,d4
move.l d1,a5
?228:
move.b (a5),d3
moveq.l #0,d0
tst.b d3
jbeq ?230
cmp.b #44,d3
jbeq ?230
cmp.b #10,d3
jbeq ?230
cmp.b #164,d3
jbeq ?230
moveq.l #1,d0
?230:
tst.l d0
jbne ?263
tst.l -14(a6)
jbge ?264
moveq.l #51,d0
jbra ?227
?264:
move.l #Vsikis,d0
move.l d0,a3
addq.w #4,a3
move.l d0,a4
addq.w #8,a4
jbra ?265
?270:
jbsr Enzan
move.l d1,-6(a6) * err
tst.l d0
jbge ?265
moveq.l #-1,d2
cmp.l -6(a6),d2
jbne ?268
move.w (a3),d0
ext.l d0
add.l d0,d0
move.l d0,a0
add.l (a4),a0
cmp.w #40,-2(a0)
jbne ?268
moveq.l #12,d0
jbra ?227
?268:
move.l -6(a6),d0
jbra ?227
?265:
tst.w (a3)
jbgt ?270
moveq.l #12,d2
add.l #Vsikis,d2
move.l d2,a0
move.l (a0),a0
move.l 12(a6),a1
move.l (a0),(a1)
cmp.b #44,d3
jbeq ?272
cmp.b #164,d3
jbeq ?272
cmp.b #10,d3
jbne ?271
?272:
addq.w #1,a5
?271:
move.l 8(a6),a1
move.l a5,(a1)
moveq.l #0,d0
cmp.b #44,d3
jbeq ?274
cmp.b #164,d3
jbeq ?274
cmp.b #10,d3
jbne ?273
?274:
moveq.l #1,d0
?273:
neg.l d0
?227:
movem.l -62(a6),d3/d4/d5/d6/d7/a3/a4/a5
unlk a6
rts
*---------------------------------------------
var_dump:
* 変数領域ダンプ
* void var_dump()
regs .reg d3-d6/a3-a4
movem.l regs,-(sp)
move.w base(pc),d0
lea bases(pc),a0 * その時の表示進数に従う
moveq.l #0,d4 * for .b = .l
move.b (a0,d0.w),d4 * bs=bases[base]
moveq.l #0,d6 * for .b = .w
lea Bsym(pc),a0
move.b (a0,d0.w),d6 * $%@
*
lea var(pc),a0
move.l vlots(a0),d3 * vlots
beq 7f * 変数がない
move.l vwork(a0),a3 * vwork
addq.l #VTOP,a3 * &vwork[VTOP]
*
5: bsr PrCRLF * 最初の改行
pea Vname(a3) * vname
DOS _PRINT * 変数名
addq.l #4,sp
bsr PrTAB
*
pea Vnum(a3)
bsr ctol * d0.l=num
addq.l #4,sp
move.l d0,d5
*
move.b Vmd(a3),d0 * md
moveq.l #VKAKU,d1
and.b d0,d1
beq @f * 確定
* 未確定
pea MesMikaku(pc)
bra 6f
*
@@: * 確定
clr.b c * エラー無しの印
lea MesDeni(pc),a4
and.b #VTYPE,d0
beq v2 * 整数
* 実数
lea MesDenf(pc),a4
cmp.l #10,d4 * 10進数?
bne @f * No
* 実数10進表示
lea kbuf(pc),a0 * 流用
move.l d5,d0 * num
moveq.l #Yuketa,d2 * 全体の桁数
FPACK __FGCVT
pea kbuf(pc)
bra 6f * 表示へ
*
@@: * 実数10進以外
tst.b fnai
bne v2 * ->内部表現表示
* 整数化表示
move.l d5,d0
FPACK __FTOL * float(d0) -> int(d0)
scs.b c * 整数化出来ないの印
bcs v2 * 整数化出来ない時はしない
@@: move.l d0,d5
*
v2: * 整数はいきなりここへ来る
move.l d4,-(sp) * 表示進数
pea kbuf(pc) * kbufを流用
move.l d5,-(sp) * num
bsr make_base * ret=d0
lea 4*3(sp),sp
lea kbuf(pc),a0
add.l d0,a0 * &kbuf[ret]
* 進数記号表示
cmp.l #10,d4
beq @f
move.w d6,-(sp)
DOS _PUTCHAR * d6.bのみ表示される
addq.l #2,sp
@@: pea (a0)
6: DOS _PRINT * 数値表示
bsr PrTAB
pea (a4) * 整数/実数
DOS _PRINT
addq.l #8,sp
*
tst.b c * 整数化出来てる?
beq @f
* 整数化出来てない
move.w #'(',-(sp)
DOS _PUTCHAR
pea MVARCCINT(pc)
DOS _PRINT * "(整数化出来ない)"を表示
move.w #')',-(sp)
DOS _PUTCHAR
addq.l #8,sp
@@: *
btst.b #BVDAI,Vmd(a3) * md&VDAI?
beq @f
bsr PrTAB
pea MesTeisu(pc) * 定数=再代入不可
DOS _PRINT
addq.l #4,sp
@@: *
moveq.l #0,d0 * for .b=.l
move.b (a3)+,d0 * len
addq.l #sizeV,d0 * len(1):md(1):num(4):vname(len):EOS
add.l d0,a3 * 次の変数へ
*
subq.l #1,d3 * 変数がある間
bne 5b
*
bsr PrCRLF * 最後の改行
7: movem.l (sp)+,regs
rts
PrTAB: move.w #TAB,-(sp)
DOS _PUTCHAR * TAB
addq.l #2,sp
rts
PrCRLF: pea CrLf2(pc)
DOS _PRINT * 改行
addq.l #4,sp
rts
*---------------------------------------------
FGETSs:
* int FGETSs(unchar *buf,int max,int fp)
* 4 8 12
* FGETCは入力がないと待ってしまうので、EOF無しファイルに対応させるには
* READを使うしかない(たぶん遅くなってしまうけど)
regs .reg d3/d4/d5
ofs = (4*3)
movem.l regs,-(sp)
move.l 4+ofs(sp),a1 * buf
move.l 8+ofs(sp),d3 * max
move.l 12+ofs(sp),d4 * fp
moveq.l #0,d2 * cc=0
moveq.l #0,d5 * len=0
*
1: pea 1.w * 1バイト読み込み
pea c(pc) * &c
move.w d4,-(sp) * fp
DOS _READ * ret=d0.l
lea 10(sp),sp
tst.l d0
ble 2f * ret<=0
move.b c(pc),d1
cmp.b #$1a,d1
beq 2f * c=$1a
cmp.b #$0a,d1
beq 2f * c=$0a
move.b d1,(a1)+ * *buf++=c
addq.l #1,d5 * len++
cmp.l d3,d5 * len>=max?
bcc 3f * Yes : バッファーオーバー
move.b d1,d2 * cc=c ; 1つ前のコード記録
bra 1b
*
3: moveq.l #-2,d0 * バッファーオーバー
bra 4f
*
2: cmp.b #$0d,d2 * cc=$0d?
bne @f * No
subq.l #1,a1 * Yes : buf-- ; CRLFは両方消す
@@: clr.b (a1) * *buf=EOS
tst.l d0 * ret==0?
seq d0
cmp.b #$1a,d1 * c=$1a?
seq d1
or.b d1,d0
moveq.l #1,d1
and.l d1,d0 * 1/0
neg.l d0 * -1/0 : EOFかどうか
4: movem.l (sp)+,regs
rts
*---------------------------------------------
vsiki_read:
* 1行内継続付き式評価処理
* int vsiki_read(unchar *line,long *num,unchar *(*err))
* 4 8 12
move.l 4(sp),a0 * line
subq.l #1,a0 * 次で+1するため
3: addq.l #1,a0
1: moveq.l #0,d0 * return(0)のため
* セパレータースキップ
move.b (a0),d1
beq 2f * EOS : 式評価終了
cmp.b #SPC,d1
beq 3b
cmp.b #TAB,d1
beq 3b
*
move.l 12(sp),a2 * *err
move.l a0,(a2) * *err=line; エラー発生点保持のため
move.l a0,line
move.l 8(sp),-(sp) * num
pea line(pc)
bsr _vsiki * ret=vsiki(&line,num);
addq.l #8,sp
move.l line(pc),a0
tst.l d0
bmi 1b * <0
2: rts
*---------------------------------------------
_vsiki_readF:
link a6,#-272
movem.l d3/d4/d5/a3/a4,-(sp)
move.l 12(a6),d5
move.l 16(a6),a0
move.l 20(a6),a4
move.l 24(a6),a3
moveq.l #-1,d3
tst.b (a0)
jbeq ?312
lea -90(a6),a1
?305:
move.b (a0)+,(a1)+
jbne ?305
move.w #32,-(sp)
pea -90(a6)
pea -272(a6)
DOS _FILES
lea 10(sp),sp
tst.l d0
jblt ?308
move.l (a3),d2
cmp.l -246(a6),d2
jbne ?310
move.w -250(a6),d2
cmp.w 6(a3),d2
jbne ?310
move.w -248(a6),d2
cmp.w 4(a3),d2
jbeq ?312
?310:
move.l -246(a6),(a3)
move.w -248(a6),4(a3)
move.w -250(a6),6(a3)
st.b ftei * 定数モード(起動時式ファイル)
jbra ?311
?318:
addq.l #1,8(a6)
?314:
move.l 8(a6),a0
move.b (a0),d0
moveq.l #0,d1
cmp.b #32,d0
jbeq ?317
cmp.b #9,d0
jbne ?316
?317:
moveq.l #1,d1
?316:
tst.l d1
jbne ?318
tst.b d0
jbne ?319
moveq.l #0,d3
jbra ?313
?319:
cmp.b #63,d0
jbeq ?320
move.l 8(a6),(a4)
move.l d5,-(sp)
pea 8(a6)
jbsr _vsiki
move.l d0,d3
addq.w #8,sp
jbra ?312
?320:
lea -90(a6),a1
move.l 8(a6),a0
jbra ?322
?325:
move.b d0,(a1)+
?322:
addq.w #1,a0
move.b (a0),d0
moveq.l #0,d1
cmp.b #32,d0
jbeq ?324
cmp.b #9,d0
jbeq ?324
cmp.b #10,d0
jbeq ?324
cmp.b #44,d0
jbeq ?324
cmp.b #164,d0
jbeq ?324
tst.b d0
jbeq ?324
moveq.l #1,d1
?324:
tst.l d1
jbne ?325
clr.b (a1)
jbra ?326
?329:
addq.w #1,a0
?326:
move.b (a0),d0
moveq.l #0,d1
cmp.b #10,d0
jbeq ?328
cmp.b #44,d0
jbeq ?328
cmp.b #164,d0
jbeq ?328
tst.b d0
jbeq ?328
moveq.l #1,d1
?328:
tst.l d1
jbne ?329
move.l a0,8(a6)
?311:
move.w #256,-(sp)
pea -90(a6)
DOS _OPEN
move.l d0,d4
addq.w #6,sp
jbge ?331
?308:
moveq.l #-1,d2
move.l d2,(a3)
move.w d2,6(a3)
move.w d2,4(a3)
moveq.l #15,d3
moveq.l #-90,d2
add.l a6,d2
move.l d2,8(a6)
jbra ?313
?341:
lea -218(a6),a0
jbra ?333
?337:
addq.w #1,a0
?333:
move.b (a0),d0
moveq.l #0,d1
cmp.b #32,d0
jbeq ?336
cmp.b #9,d0
jbne ?335
?336:
moveq.l #1,d1
?335:
tst.l d1
jbne ?337
tst.b d0
jbeq ?331
cmp.b #10,d0
jbeq ?331
cmp.b #59,d0
jbeq ?331
move.l a4,-(sp)
move.l d5,-(sp)
move.l a0,-(sp)
jbsr vsiki_read
move.l d0,d3
lea 12(sp),sp
jbgt ?332
?331:
move.l d4,-(sp)
pea 128.w
pea -218(a6)
jbsr FGETSs
move.l d0,d3
lea 12(sp),sp
jbeq ?341
?332:
moveq.l #-2,d2
cmp.l d3,d2
jbne ?342
moveq.l #16,d3
move.l a6,d2
add.l #-218,d2
move.l d2,(a4)
?342:
clr.b ftei * 1回起動式ファイルを読んだら定数モードを解除
move.w d4,-(sp)
DOS _CLOSE
addq.w #2,sp
tst.l d3
jbgt ?313
?312:
tst.l d3
jblt ?314
?313:
move.l d3,d0
movem.l -292(a6),d3/d4/d5/a3/a4
unlk a6
rts
*---------------------------------------------
ErrorSearch:
* エラーメッセージサーチ
* unchar *ErrorSearch(int ecode)
move.w 4+2(sp),d1 * ecode
lea ERRmes(pc),a1
lea ERRvsiki(pc),a0 * eno.w
@@: move.w (a0)+,d0 * eno
beq 2f * NULL -> end (NULLを返す)
cmp.w d0,d1 * eno==ecode?
beq 1f * 一致
3: tst.b (a1)+ * to next mes
bne 3b
bra @b
*
1: move.l a1,d0
rts * return(mes)
2: moveq.l #0,d0 * return(NULL)
rts
*---------------------------------------------
VARINITS macro
* 変数領域をクリアする
* なぜマクロにするのかはInitWorkを参照のこと
local L1
lea var(pc),a1
move.l (a1),a0 * var.vwork
clr.b (a0) * vwork[0]=0
clr.l vlots(a1) * vlots=0
* ハッシュテーブル初期化
move.l vhash(a1),a0 * var.vhash
move.w vhsize(a1),d0 * var.vhsize
subq.w #1,d0 * -1 for dbra
L1: clr.l (a0)+ * for (i=0;i<vhsize;i++) vhash[i]=0;
dbra d0,L1
endm
VarInit:
* 変数領域をクリアする
VARINITS
* 次回起動時式ファイル読み込み必要
moveq.l #-1,d0
move.l d0,fsizeI
move.l d0,fdateI * ftimeIもクリアする
move.l d0,fsizeF
move.l d0,fdateF * ftimeFもクリアする
rts
*---------------------------------------------
Deni: * 整数
move.w #NOT_ASCII|XF1_KEY,xfkey+2 * 操作キーの変更
clr.b ffloat
bra Den
*
Denf: * 実数
move.w #NOT_ASCII|XF2_KEY,xfkey+2 * 操作キーの変更
st.b ffloat
clr.b hugo * 内部的には符号なし扱いになる
*
Den: * 共通メインルーチン
cmp.b #$ff,first * 前回エラー?
bne @f * No
* 前回エラーが出ているので、終了してしまう。
* 入力ラインの修正が必要。
move.b #1,first
move.l #CACI_END,d0
rts
*
@@: move.w 4+2(sp),d2 * BIT16K キーコード
move.l d3,-(sp) * push d3
move.w #CACI_NORMAL,d3 * ret=規定外キー入力の時のため
*
bsr BREAKOFF
*
move.w base(pc),d0
lea bases(pc),a0
move.b (a0,d0.w),d6 * bs=bases[base]
*
* キーを探して各ルーチンへ飛ぶ
lea Jtable(pc),a0
move.w d2,d1
and.w #NAKEY,d1
@@: move.l (a0)+,d0 * jump|code
beq @f * -> end of table
cmp.w d1,d0 * =code?
bne @b * no
clr.b eover * オーバーフローフラグクリア
swap d0 * d0=jump
jsr -4(a0,d0.w)
*
@@: bsr BREAKON
*
moveq.l #0,d0 * for .w = .l
move.w d3,d0
move.l (sp)+,d3 * pop d3
rts
*------------------------------------
Jtable: * 各キー毎のジャンプテーブル(出てきやすい順に並べる)
* jump先(offset),code
* CTRL+SHIFT+XF1/XF2 : 起動/終了
* ↑↓/XF1/SHIFT+XF1/XF2 : 表示進数選択
* CR : 決定&終了
* ESC : 終了
xfkey: .dc.w xf1key-$,NOT_ASCII|XF1_KEY * <-ここがXF2_KEYに変わる
.dc.w crkey-$,CR
.dc.w downkey-$,NOT_ASCII|DOWN_KEY
.dc.w upkey-$,NOT_ASCII|UP_KEY
.dc.w esckey-$,ESC
.dc.w key0-$,'0'
.dc.w key2-$,'2'
.dc.w key6-$,'6'
.dc.w key8-$,'8'
.dc.w keyplus-$,'+'
.dc.w keyminus-$,'-'
.dc.w xf5key-$,NOT_ASCII|XF5_KEY
.dc.w f10-$,NOT_ASCII|FKEY10_KEY
.dc.w f1-$,NOT_ASCII|FKEY1_KEY
.dc.w 0,0 * end of table
*------------------------------------
key0: * '0' : 10進数表示
move.w #0,base
bra DEX
key6: * '6' : 16進数表示
move.w #1,base
bra DEX
key2: * '2' : 2進数表示
move.w #2,base
bra DEX
key8: * '8' : 8進数表示
move.w #3,base
bra DEX
keyplus: * '+' : 符号なし表示
tst.b ffloat
bne BEEP * float時には無効
clr.b hugo
bra DEX
keyminus: * '-' : 符号あり表示
tst.b ffloat
bne BEEP * float時には無効
st.b hugo
bra DEX
f1: * 内部表現表示切り替え
tst.b ffloat
beq BEEP * 整数時には無効
not.b fnai
bra DEX
f10: * 変数ダンプ
bsr var_dump
rts
BEEP: moveq.l #7,d1
IOCS _B_PUTC
rts
*------------------------------------
upkey: * ↑
move.w base(pc),d0
subq.w #1,d0
bpl @f
move.w #BMAX-1,d0
@@: move.w d0,base
bra DEX
*
downkey:* ↓
move.w base(pc),d0
addq.w #1,d0
cmp.w #BMAX,d0
bcs @f * <BMAX
moveq.l #0,d0
@@: move.w d0,base
bra DEX
xf5key: * XF5 : 全角-半角
not.b fzen * 交互変換
bra DEXZ
*------------------------------------
crkey: * CR : 決定終了
* すでにcbufに代入されているのでそれを返すだけ
move.w #DF_OUTSTR|CACI_END,d3 * 出力
move.b #1,first * first=1
rts
xf1key: * XF1/XF2 : 起動
btst.l #B_CTRL_ON,d2 * btstは.b/.lしかないため
bne @f * +CTRLである
* +CTRLでない
btst.l #B_SHIFT_ON,d2 * btstは.b/.lしかないため
bne upkey * +SHIFTである : ↑
bra downkey * +SHIFTでない : ↓
*
@@: * CTRL+...
btst.l #B_SHIFT_ON,d2 * btstは.b/.lしかないため
beq upkey * +SHIFTはない : ↑
* CTRL+SHIFT+XF1/XF2:起動
tst.b first
bne @f
* 2回目はキャンセルで終了
esckey: * ESC
move.w #CACI_END,d3 * 終了
move.b #1,first * first=1
rts
*
@@: * 起動した -> 計算
clr.b first * first=0(sf firstでも全く同じ;同サイズ/クロック)
*
lea cbuf(pc),a0
moveq.l #0,d1 * for .b = .l
move.b (a0),d1
bsr kcheck1 * 1文字目が全角?
beq @f * No : 半角化しない
* 半角化
pea (a0) * cbuf (des)
pea (a0) * cbuf (src)
pea 14.w
DOS _KNJCTRL * 上書きで全角→半角
lea 12(sp),sp
*
@@: * 式評価(連続)
lea cbuf(pc),a1
cmp.b #'、',(a1) * '、'で始まる?
beq 61f * Yes
cmp.b #',',(a1) * ','で始まる?
bne @f * No
61: addq.l #1,a1 * ','/'、'を飛ばして実行
bsr VarInit * 変数クリア
*
@@: lea preexecI(pc),a0 * 整数式ファイル
lea fsizeI(pc),a2 * 更新判定
tst.b ffloat * 実数?
beq 60f * No
lea preexecF(pc),a0 * 実数式ファイル
lea fsizeF(pc),a2 * 更新判定
60: pea (a2)
pea err(pc)
pea (a0) * 式ファイル名
pea num(pc)
pea (a1) * cbuf(変換ラインの式)
bsr _vsiki_readF * -> d0.l(ret2)
lea 20(sp),sp
tst.l d0
ble DEX * ret2<=0
*
* エラー発生
move.l d0,-(sp)
bsr ErrorSearch * -> d0.l : エラーメッセージ
addq.l #4,sp
* ここでNULLが返ってくることがあるということは内部エラーである
tst.l d0 * NULL?
bne @f * No
move.l #InErr,d0 * 内部エラー(念のため入れておく)
@@: move.l d0,a1
move.l #C_SIZE,d0
lea kbuf(pc),a3 * 一旦kbufに格納する
@@: subq.l #1,d0
move.b (a1)+,(a3)+
bne @b
subq.l #1,a3 * EOSに戻す
addq.l #1,d0
lea MesError(pc),a1 * セパレーター
@@: subq.l #1,d0
move.b (a1)+,(a3)+
bne @b
subq.l #1,a3 * EOSに戻す
addq.l #1,d0
move.l err(pc),a1 * エラー発生場所
@@: subq.l #1,d0
bne 11f
clr.b (a3)+
bra 12f
11: move.b (a1)+,(a3)+
bne @b
12: lea kbuf(pc),a1
lea cbuf(pc),a3 * kbuf->cbuf(エラーはcbufへ直接入れる)
@@: move.b (a1)+,(a3)+
bne @b
st.b first * first=$ff
bra 99f
*
DEX: * 変換ラインに表示して選択
* 数値 -> kbuf
move.w base(pc),d0
lea bases(pc),a0
move.b (a0,d0.w),d6 * bs=bases[base]
moveq.l #0,d0 * for .b = .l
move.b d6,d0
*
tst.b hugo
beq @f * 符号なし
* 符号あり
neg.l d0 * d0=-d0
@@: move.l num(pc),d2 * 数字
tst.b ffloat * 実数?
beq 80f * No -> 整数
* 実数
cmp.l #10,d0 * 10進数?
bne 81f * No -> 2/8/16進数
* 実数10進表示(常に普通表示)
lea cbuf0(pc),a0 * 一度cbuf0に作る
move.l d2,d0
moveq.l #Yuketa,d2 * 全体の桁数
FPACK __FGCVT * floatだけ変換
bra DEXZ
*
81: * 実数2/8/16進表示
tst.b fnai * 内部表現表示?
bne 80f * Yes
* 普通表示->整数化表示
move.l d0,-(sp)
move.l d2,d0
FPACK __FTOL * float(d0) -> int(d0)
scs.b eover * 整数化出来ない時はc=$ffになる
bcs @f * 整数化出来ない時は元のまま
move.l d0,d2 * 整数化出来た
@@: move.l (sp)+,d0 * 進数
*
80: move.l d0,-(sp) * 進数
pea cbuf0(pc) * 一度cbuf0に作る
move.l d2,-(sp) * 数字
bsr make_base * 数値文字列化->cbuf
lea 12(sp),sp
tst.l d0 * ret2==0?
beq DEXZ * Yes
lea cbuf0(pc),a0
lea (a0,d0.l),a1
@@: move.b (a1)+,(a0)+ * strcpy(cbuf,&cbuf[ret2]); // cbuf[0]からに入れるため
bne @b
tst.b eover * 整数化出来ないエラーが出ている?
beq DEXZ * No
* 整数化出来ていない
subq.l #1,a0 * EOSを消すため
move.b #'(',(a0)+
lea MVARCCINT(pc),a1
@@: move.b (a1)+,(a0)+ * "(整数化出来ない)"を追加
bne @b
move.b #')',-1(a0)
clr.b (a0) * EOS
*
DEXZ: * 全角-半角
lea cbuf0(pc),a0
tst.b fzen * 全角化?
bne 98f * Yes
* 半角化;実際はcbuf0->cbufだけ
lea cbuf(pc),a1
@@: move.b (a0)+,(a1)+
bne @b
bra 99f
*
98: * 全角化
pea cbuf(pc) * cbuf (des)
pea (a0) * cbuf0 (src)
pea 13.w
DOS _KNJCTRL * 半角→全角
lea 12(sp),sp
*
99: lea cbuf(pc),a0
cmp.b #$ff,first * error?
seq.b d1
moveq.l #1,d0
and.l d0,d1 * エラーの時は反転表示
*
move.l #kbuf,d0
bsr Str2MEANS
* タイトル -> mbuf
lea Title(pc),a0
moveq.l #'+',d0
tst.b hugo
beq @f
moveq.l #'-',d0
@@: move.b d0,(a0) * Title[0]=(hugo? '-':'+');
moveq.l #'0',d0
cmp.b #10,d6 * bs>=10?(実際には16のみ)
bcs @f * No
moveq.l #'1',d0
sub.b #10,d6 * 16 -> 6 , 10 -> 0
@@: move.b d0,1(a0) * Title[1]='0'+(bs>=10);
add.b #'0',d6
move.b d6,2(a0) * Title[2]='0'+(bs%10);
* 実数/整数表示
moveq.l #' ',d1
move.w #'整',d0 * 整数
tst.b ffloat
beq @f
move.w #'実',d0 * 実数(整数化)
tst.b fnai * 内部表現表示?
beq @f
moveq.l #'*',d1 * 実数(内部表現)
@@: move.w d0,6(a0) * Title[6,7]='整'/'実';
move.b d1,10(a0) * Title[10]=' '/'*'
*
move.l #mbuf,d0
moveq.l #1,d1 * 反転表示
move.w #DF_KWINSTR|DF_MWINSTR|CACI_NORMAL,d3
* 以下サブルーチンにつながる * mbuf[Str2MEAN(Title,mbuf,1)]=0;
Str2MEANS:
* buf[Str2MEAN(mes,buf,mode)]=0
* a0 <- mes
* d0.l <- buf
* d1.l <- mode (0=通常表示,1=反転表示)
move.l d1,-(sp) * mode
move.l d0,-(sp) * buf
pea (a0) * mes
pea 62.w
DOS _KNJCTRL
lea 4*4(sp),sp
move.l -8(sp),a0 * buf
add.w d0,d0 * .w=MEAN
clr.w (a0,d0.w) * buf[..]=0
rts
******************************************************************************
* ワーク2
******************************************************************************
* ここに置くワークは、常駐後に使われるもの
* これらのワークエリアは常駐後に利用可能になるので、
* 以下の非常駐ルーチンからは参照しないこと
*--------------------------------------------------------------------
* オフセットテーブルの定義
.offset 0
*--------------------------------------------------------------------
_brksts .ds.w 1 * BREAKフラグ
_kbuf .ds.w K_SIZE * 変換ラインへ
_mbuf .ds.w M_SIZE * モード表示領域へ
_cbuf .ds.b C_SIZE * 仮入力行 -> 入力行へ(半角/全角)
_cbuf0 .ds.b C_SIZE * 計算結果文字列(常に半角)
_num .ds.l 1
_err .ds.l 1
_line .ds.l 1
_c .ds.b 1
_eover .ds.b 1 * 整数化でのオーバーフロー
_ifflag .ds.b 1 * その演算子が整数/floatどちらで使えるか
.even
_keep_end .ds.w 0 * オフセットのみ
*--------------------------------------------------------------------
* 実際のワークエリアの定義
*--------------------------------------------------------------------
.text * .offset解除
work2:
brksts equ work2+_brksts
kbuf equ work2+_kbuf
mbuf equ work2+_mbuf
cbuf equ work2+_cbuf
cbuf0 equ work2+_cbuf0
num equ work2+_num
err equ work2+_err
line equ work2+_line
c equ work2+_c
eover equ work2+_eover
ifflag equ work2+_ifflag * float
*********************************************************************
* ワークエリア初期化
*********************************************************************
* ワークエリアを低位メモリーに取るとき、mallocではなく常駐メモリーを多く取って
* プログラムの後ろに付ける。これは、メモリーの分断を防ぐためである。
*
InitWork:
* a2.l <- 元のvwork
* d6.l <- 常駐サイズ
VARINITS * ワークエリア初期化
* ワークエリアのクリアにおいて、initspで設定されたスタックも破壊してしまう。
* このためこの中ではサブルーチン呼び出しが出来ない。
* そのためにここに直接書いている(他でも使うのでマクロ化)。
*
tst.b fhigh * /H?
bne @f * Yes
* 低位メモリーの時;高位メモリーワーク解放
pea (a2) * 元var.vwork
DOS _MFREE
addq.w #4,sp * めんどうなのでエラー処理は省略
@@: clr.w -(sp) * exit(0)相当
move.l d6,-(sp) * 常駐サイズ
DOS _KEEPPR
InitWorkEnd:
* InitWorkが上のワークに含まれないとおかしくなるけど、今のサイズなら大丈夫だろう
*--------------------------------------------------------------------
* 転送ルーチンサイズ<ワークエリアサイズである
* 常駐部分最後
KEEP_END equ work2+_keep_end
******************************************************************************
* 非常駐ルーチン
******************************************************************************
* アクセサリ定義構造体
******************************************************************************
.even
ACdef:
* 整数
.dc.w KS_EDITING|KS_SELECT * 仮入力時+仮確定時のみ
.dc.w NOT_ASCII|CTRL_ON|SHIFT_ON|XF1_KEY * 呼びだしキー
.dc.l Deni * アクセサリーメイン
.dc.l cbuf
.dc.l kbuf
.dc.l mbuf
* 1つの構造体のサイズは20バイト
* 実数
.dc.w KS_EDITING|KS_SELECT * 仮入力時+仮確定時のみ
.dc.w NOT_ASCII|CTRL_ON|SHIFT_ON|XF2_KEY * 呼びだしキー
.dc.l Denf * アクセサリーメイン
.dc.l cbuf
.dc.l kbuf
.dc.l mbuf
******************************************************************************
* 式・変数処理初期化
******************************************************************************
Vsopen1:
move.l 4(sp),d0 * vsize
* vsizeの補正は外部で行われているのでここでは行わない
lea var(pc),a0
move.l d0,vwsize(a0) * var.vwsize
move.l d0,a1 * vwsize
*
* ハッシュエリアサイズ計算(16bitサイズ)
lsr.l #4,d0 * d0/16
cmp.l #65536,d0
bcs @f * <65536(16bit)
move.l #65535,d0 * max 65535
@@: cmp.l #1024,d0
bcc @f * >=1024
move.l #1024,d0 * min 1024
@@: move.w d0,vhsize(a0) * var.vhsize
add.l d0,d0
add.l d0,d0 * vhsize*LLONG
add.l d0,a1 * vwsize+vhsize*LLONG
*
* ワークエリアサイズ計算(変数/ハッシュ一括/全スタック確保)
lea Vsikis(pc),a0
move.w emax(a0),d0 * emax
add.w d0,a1
add.w d0,a1 * +emax*LSHORT(2) : estack.w
moveq.l #0,d0 * for .w = .l
move.w vmax(a0),d0 * vmax
lsl.l #3,d0 * *8(LLONG*2) : vstack.l+pstack.l
add.l d0,a1
move.l a1,d0 * ret
rts
*--------------------------------------------------------------------
Vsopen2:
* ワークエリアアドレスの設定
* var.vworkにその先頭アドレスが入っている
lea var(pc),a0
move.l vwork(a0),d0 * var.vwork
add.l vwsize(a0),d0 * +vwsize
move.l d0,vhash(a0) * var.vhash=(long *)&var.vwork[var.vwsize];
*
moveq.l #0,d1 * for .w = .l
move.w vhsize(a0),d1 * vhsize
add.l d1,d1
add.l d1,d1 * *4 for .l (vhashはlong[])
add.l d1,d0 * vhash[vhsize]
lea Vsikis(pc),a0
move.l d0,estack(a0) * Vsikis.estack=(unsint *)&var.vhash[var.vhsize];
*
moveq.l #0,d1 * for .w = .l
move.w (a0),d1 * emax
add.l d1,d1 * *2 for .w (estackはunsint[])
add.l d1,d0
move.l d0,vstack(a0) * Vsikis.vstack=(long *)&Vsikis.estack[Vsikis.emax];
*
moveq.l #0,d1 * for .w = .l
move.w vmax(a0),d1 * vmax
add.l d1,d1
add.l d1,d1 * *4 for .w (vstackはlong[])
add.l d1,d0
move.l d0,pstack(a0) * Vsikis.pstack=(long *)&Vsikis.vstack[Vsikis.vmax];
*
rts
******************************************************************************
* アクセサリ 組み込み/解除/初期化
*******************************************************************************
DeleteAcc:
* アクセサリの解除(現在登録されているもの全て)
* 入力:a2 = ACh(内部/外部)
* 出力:d0.l = 0:ok , !=0:エラー
* 破壊:d0
regs .reg d1-d2/a0-a3
movem.l regs,-(sp) * push regs
moveq.l #0,d1 * ret=0
lea ACdef(pc),a3 * アクセサリ構造体(内部=外部)
lea ACnames(pc),a1 * アクセサリ名
moveq.l #ACCS-1,d2 * アクセサリの数 -1 for dbra
1: tst.l (a2) * ACh[i]>=0?
bmi 2f * No : 未登録
lea MesAcc(pc),a0
bsr Print * アクセサリ「
move.l (a1),a0
bsr Print * アクセサリ名
move.l (a2),-(sp) * ACh[i]
pea 61.w
DOS _KNJCTRL
addq.l #4*2,sp
tst.l d0
beq @f * ret=0:Ok
* Error
moveq.l #1,d1 * ret=1
lea ErrCantDelete(pc),a0 * error
bra 3f
@@: * ok
move.l #-1,(a2) * 未登録にする
lea MesDeleteOk(pc),a0 * ok message
3: bsr Print
2: addq.l #4,a1 * next name
addq.l #4,a2 * next ACh
lea 20(a3),a3 * next ACdef
dbra d2,1b
move.l d1,d0 * ret
movem.l (sp)+,regs * pop regs
rts
*******************************************************************************
AttachAcc:
* アクセサリの登録(登録リストに従う)
* この登録前には一度全てのアクセサリが解除されていること。
* 入力:a2 = ACh内部
* 出力:d0.l = 0:ok , !=0:エラー
* 破壊:d0
regs .reg d1-d3/a0-a3
movem.l regs,-(sp) * push regs
* ASKのバージョンチェック
pea 50.w
DOS _KNJCTRL
addq.l #4,sp
cmp.l #300,d0 * <300? (V3.00未満?)
bcc @f * No (V3.00以降)
* ASK V3.00以降でない
lea ErrASK3(pc),a0
bsr EPrint
moveq.l #3,d1 * return(3)
bra 1f
*
@@: * アクセサリの登録
* AChの初期値は全て-1であること
move.l a2,d3 * ACh保存
moveq.l #0,d1 * ret=0
lea ACdef(pc),a3 * アクセサリ構造体(内部=外部)
lea ACnames(pc),a1 * アクセサリ名(内部=外部)
moveq.l #ACCS-1,d2 * アクセサリの数 -1 for dbra
2: lea MesAcc(pc),a0
bsr Print * アクセサリ「
move.l (a1),a0
bsr Print * アクセサリ名
pea (a3) * ACdef
pea 60.w
DOS _KNJCTRL
addq.l #4*2,sp
cmp.l #-1,d0 * error?
bne @f * no
* アクセサリに登録出来ない
lea ErrCantAttach(pc),a0
bsr Print
bsr PrCRLF
* 今までに登録出来たものを全て削除する
move.l d3,a2 * ACh復帰
bsr DeleteAcc
moveq.l #4,d1 * return(4)
bra 1f
*
@@: * Ok
move.l d0,(a2) * ACh[i]=ret
lea MesAttachOk(pc),a0
5: bsr Print
3: addq.l #4,a1 * next name
addq.l #4,a2 * next ACh
lea 20(a3),a3 * next ACdef
dbra d2,2b
1: move.l d1,d0 * ret
movem.l (sp)+,regs * pop regs
rts
******************************************************************************
EPrint:
* エラー出力に表示する
* 表示は全てこれで行っている
* 入力:a0 = 文字列
* 破壊:なし
move.l d0,-(sp) * push d0
move.w #2,-(sp) * STDERR
pea (a0) * 文字列
DOS _FPUTS * エラー出力へ
addq.l #2+4,sp
move.l (sp)+,d0 * pop d0
rts
Print:
* 標準出力に表示する(リダイレクト可)
* 入力:a0 = 文字列
* 破壊:なし
move.l d0,-(sp) * push d0
pea (a0) * 文字列
DOS _PRINT
addq.l #4,sp
move.l (sp)+,d0 * pop d0
rts
******************************************************************************
* この中ではa0/a2は壊さないこと(プロセス管理ポインタ/コマンドラインを参照するため)
AMAX equ 10 * 最大引数数
* コマンドライン
* a2
* 0(a2) = コマンドライン長
* 1(a2)~ = コマンドライン
* '-r ',0 スペース/タブはそのまま
*
GetArgv:
* コマンドラインを解析して各要素の先頭アドレスをargvに、個数をargcに格納する
* 引数:a2 = コマンドライン
* 出力:d0.w = 引数数(=argc)
* 破壊:d0-d1
regs .reg a2/a6
movem.l regs,-(sp)
moveq.l #0,d1 * 引数数
tst.b (a2)+ * コマンドライン長を飛ばす
beq 2f * コマンドライン長=0 -> 引数なし
lea argv(pc),a6
@@: * SPC/TAB skip
move.b (a2)+,d0
beq 2f * コマンドライン終わり
cmp.b #SPC,d0 * skip SPC
beq @b
cmp.b #TAB,d0 * skip TAB
beq @b
* SPC/TAB以外の文字が有った
subq.l #1,a2
move.l a2,(a6)+ * argv記録
addq.w #1,d1 * 引数+1
cmp.w #AMAX,d1 * 最大数を越える?
bcc 2f * -> 越える
1: * 次のEOS/SPC/TABまで飛ばす
move.b (a2)+,d0
beq 2f * コマンドライン終わり
cmp.b #SPC,d0 * skip SPC
beq @b
cmp.b #TAB,d0 * skip TAB
bne 1b
bra @b
*
2: move.w d1,argc * 記録
move.w d1,d0
movem.l (sp)+,regs
rts
*---------------------------------------------
CheckOption:
* コマンドラインから指定オプションを探す
* 必ずGetArgvを呼び出した後に使うこと
* オプション名は先頭1文字だけで判別
* 引数:d2.b = オプション名(英小文字1文字/大文字の時は直後の文字列をa6に転送)
* a6.l = 直後文字列転送エリアアドレス
* 出力:d0.l = 0:なし , !=0:そのオプションの次のアドレス
* 破壊:d0-d1
regs .reg d7/a4-a6
movem.l regs,-(sp)
moveq.l #0,d7 * 後ろ引数取り込まない
cmp.b #'a',d2 * オプション名'a'>=?
bcc @f * Yes
moveq.l #1,d7 * 英大文字;後ろ引数取り込む
or.b #$20,d2 * 小文字化
*
@@: move.w argc(pc),d1
beq 1f * 引数はない
subq.w #1,d1 * -1 for dbra
lea argv(pc),a4
@@: move.l (a4)+,a5 * argv[i]
move.b (a5)+,d0 * argv[i][0]
* オプションの1文字目は'/''-'
cmp.b #'/',d0
beq 2f
cmp.b #'-',d0
beq 2f
3: dbra d1,@b * 次へ
1: * (指定)オプションはない
moveq.l #0,d0
bra 4f
2: * '/''-'があった
move.b (a5)+,d0 * 次の1文字
or.b #$20,d0 * 英小文字化
cmp.b d2,d0 * 一致?
bne 3b * -> 不一致
move.l a5,d0 * オプション名の次のアドレス(!=0)
tst.w d7 * 後ろ取り込む?
beq 4f * No
* 後ろ引数の取り込み -> a6
* d0=a5 ; オプション名の次のアドレス(!=0)
@@: move.b (a5)+,d1
beq 5f * EOS
cmp.b #SPC,d1
beq 5f
cmp.b #TAB,d1 * EOS/SPC/TABまで
beq 5f
move.b d1,(a6)+
bra @b
*
5: clr.b (a6) * EOS
4: movem.l (sp)+,regs
rts
******************************************************************************
* メイン
******************************************************************************
.xref keepchk
.xref Atoi
.xref _ChkEX68
main:
lea.l initsp(pc),sp * PROGRAM=の時のため
* タイトル表示
move.w #2,-(sp) * STDERR
pea title(pc) * 文字列
DOS _FPUTS * エラー出力へ
addq.l #2+4,sp
*
jbsr _ChkEX68 * EX68のチェック
bne Err_EX68 * 動作不可とする(将来外す可能性はある)
*
move.l #(id-KEEP_START),-(sp) * 識別子の相対位置
pea.l (a0) * 自分のメモリ管理ポインタ
bsr keepchk * 常駐チェック
addq.l #4*2,sp
move.b d0,d7 * d7 :0=常駐してない , -1=常駐している
* 引数チェック1
bsr GetArgv * argc/argv設定
*tst.w d0
*beq usage * 引数がない -> 説明表示
* ASKDen V2は引数なし
moveq.l #'r',d2 * -r : 常駐解除?
bsr CheckOption
tst.l d0
beq keep * no
*
* 常駐解除
*
tst.b d7 * 常駐している?
beq Err_NoKp * No -> error
* a0=常駐しているルーチンのメモリ管理ポインタ
* メモリー管理ポインタを飛ばし、ユーザープログラム先頭へ
* さらに、AChまで飛ばす
lea fhigh-KEEP_START+PSPSIZ(a0),a4 * fhighのアドレス
tst.b (a4) * ワークは高位メモリー?
beq @f * No : 低位メモリーの時は解放ずみ
lea var-KEEP_START+PSPSIZ(a0),a2 * var.vwork
move.l (a2),-(sp) * varのアドレス
DOS _MFREE * メモリー解放
addq.w #4,sp
@@: lea.l ACh-KEEP_START+PSPSIZ(a0),a2 * AChのアドレス
bsr DeleteAcc * アクセサリ解除
tst.l d0
bne Err_Kai * アクセサリ登録削除不可により常駐解除不可
*
pea.l MPSIZ(a0)
DOS _MFREE * 自己プロセスメモリー解放
addq.l #4,sp
tst.l d0
bmi Err_Kai * なぜかメモリー解放出来ない時
*
* 常駐解除正常終了
lea MesRelease(pc),a0
bsr Print
clr.w -(sp) * exit(0)
DOS _EXIT2
keep: * 常駐
tst.b d7 * 常駐している?
bne Err_Dbl * Yes -> error(2重常駐)
*
* プログラム起動時にはフリーエリアの全てが起動プログラムに割り当てられているため、
* これを必要部分以外解放する。そうしないとMALLOCが効かない。
* a0=プログラムメモリ管理ポインタ
* a1=プログラム終了アドレス+1(.data,.bssを含む)
lea MPSIZ(a0),a0 * メモリー管理ポインタ分を飛ばす
move.l a0,ProcAD * このプロセスの先頭アドレス保存
sub.l a0,a1 * 当プログラムサイズ
move.l a1,-(sp) * 確保する領域サイズ
move.l a0,-(sp) * 確保する領域の先頭アドレス
DOS _SETBLOCK * 空き領域確保
addq.w #4*2,sp
tst.l d0
bmi Err_Mem * 領域が確保できない時=エラー
*
* 式・変数処理初期化1
lea work(pc),a6
moveq.l #'W',d2 * -Wsize : ワークエリアサイズ(size,0->(a6))
bsr CheckOption
move.l #1024,d2 * デフォルト変数領域サイズ
tst.l d0
beq @f * サイズ指定なし
* サイズ指定あり : サイズ読み取り
bsr Atoi * 読み取り (size/sizeK) -> d0.l (d0/d1/a6破壊)
* サイズ判定
move.l #256,d2 * 最小変数領域サイズ
cmp.l d2,d0
bcs @f * <d2 -> d2
btst.l #0,d0 * BIT0=1? : 奇数?
beq 11f * No
addq.l #1,d0 * +1して偶数にする
11: move.l d0,d2
*
@@: move.l d2,-(sp) * ワークエリアサイズ
bsr Vsopen1 * -> d0.l : 必要ワークエリアサイズ計算
addq.l #4,sp
move.l d0,all * サイズ記録
*
move.l d0,-(sp) * 必要サイズ
move.w #2,-(sp) * 高位メモリー
DOS _MALLOC2 * ワークエリア確保
addq.l #6,sp
tst.l d0
bmi Err_Mem * 確保出来ない
move.l d0,var * アドレス記録(var.vwork)
*
* アクセサリ組み込み
lea ACh(pc),a2
bsr AttachAcc
tst.l d0
bne Err_Keep * 組み込みエラー
*
* アクセサリも組み込みOK
lea MesKeep(pc),a0
bsr Print
*
* オプション処理
lea preexecI(pc),a6
clr.b (a6) * 指定なしの時のため
moveq.l #'I',d2 * -Ifname : 整数式ファイル名
bsr CheckOption
*
lea preexecF(pc),a6
clr.b (a6) * 指定なしの時のため
moveq.l #'F',d2 * -Ffname : 実数式ファイル名
bsr CheckOption
*
moveq.l #'p',d2 * -p : 表示符号なし
bsr CheckOption
tst.l d0
seq hugo * -pなし=符号あり
*
lea work(pc),a6
moveq.l #'S',d2 * -Smode : 表示進数[mode=0,1,2,3]
bsr CheckOption
move.l #0,d2 * デフォルト:10進数
tst.l d0
beq @f * 指定なし
* 指定あり : モード読み取り
bsr Atoi * 読み取り -> d0.l (d0/d1/a6破壊)
* サイズ判定
cmp.l #3,d0
bhi @f * >3は0とみなす
tst.l d0
bmi @f * <0も0とみなす
move.l d0,d2
@@: move.w d2,base
*
move.l #KEEP_END-KEEP_START,d6 * 基本常駐サイズ
moveq.l #'h',d2 * -h : 高位メモリー?
bsr CheckOption
tst.l d0
bne 10f * Yes
*
* 低位メモリーの時
clr.b fhigh * 低位メモリー確保の印
*
* ワークエリアアドレス変更
* このプロセスの占めるメモリー領域を拡大してワークも入るようにする
add.l all(pc),d6 * ワークエリアサイズ
move.l d6,d0
add.l #PSPSIZ-MPSIZ,d0 * プロセス管理ポインタ分も含める
move.l d0,-(sp) * new size
move.l ProcAD(pc),-(sp)
DOS _SETBLOCK
addq.w #8,sp
bmi Err_Mem * メモリー不足
*
move.l #var,varad * varのアドレスを記録
*
* ワークエリアポインターを変更
move.l var(pc),a2 * 元のvar.vwork
move.l #KEEP_END,var * var.vworkをKEEP_ENDに変更
*
10: bsr Vsopen2 * 式・変数初期化2(アドレス設定)
bra InitWork
*
* エラー終了
*
Err_EX68: * EX68上である
lea.l ErrEX68(pc),a0
bra.s error
Err_Mem: * メモリーが不足している
lea.l ErrCantGetWrk(pc),a0
bra error
Err_NoKp: * 常駐していないのに解除しようとした
lea.l NoKeep(pc),a0
bra.s error
Err_Dbl: * 2重常駐
lea.l AlreadyKeep(pc),a0
bra.s error
Err_Keep: * 常駐できない
lea.l CantKeep(pc),a0
bra.s error
Err_Kai: * 常駐解除不可
lea.l CantRelease(pc),a0
bra.s error
usage: * 使用法
lea.l MesUsage(pc),a0
error: move.l var(pc),d0
beq @f * ワークエリアは確保されていない
move.l d0,-(sp)
DOS _MFREE * ワークエリア解放
addq.l #4,sp
@@: bsr EPrint * エラー出力へ表示
erRet: move.w #2,-(sp) * exit(2)
DOS _EXIT2
******************************************************************************
* メッセージなど
******************************************************************************
.even
ACnames * メッセージアドレス表
* アクセサリ構造体の並びと同じ
.dc.l MesDeni
.dc.l MesDenf
*
MesAcc: .dc.b 'アクセサリ「電卓(式評価);',0
MesDeleteOk: .dc.b '」を削除しました',CR,LF,0
ErrCantDelete: .dc.b '」が削除できません',CR,LF,0
ErrCantAttach: .dc.b '」が登録できません',CR,LF,0
MesAttachOk: .dc.b '」を登録しました',CR,LF,0
ErrASK3: .dc.b 'ASK v3/codeAではありません',CR,LF,0
title: .dc.b 'ASK3/codeAアクセサリ ASKDen V2.02',CR,LF
.dc.b TAB,'Copyright 1998-99 by AIG-Soft',CR,LF
Eoss .dc.b 0
MesKeep: .dc.b '常駐しました',CR,LF,0
MesRelease: .dc.b '常駐解除しました',CR,LF,0
NoKeep: .dc.b '常駐していません',CR,LF,0
AlreadyKeep: .dc.b 'すでに常駐しています',CR,LF,0
CantKeep: .dc.b '常駐できません',CR,LF,0
CantRelease: .dc.b '常駐解除できません',CR,LF,0
MesUsage: .dc.b 'ASKDen2 [/I整数式ファイル /F実数式ファイル /P /Smode /Wsize /H /R]',CR,LF,0
* メッセージ
ErrCantGetWrk: .dc.b 'ワークエリアが確保できません',CR,LF,0
ErrEX68 .dc.b 'EX68上では組み込めません',CR,LF,0
.even
argc .ds.w 1 * 引数の個数
argv .ds.l AMAX * 各引数の先頭アドレス
******************************************************************************
* 非常駐ルーチンが使うワーク
******************************************************************************
.bss
.even
ProcAD .ds.l 1 * このプロセスの先頭アドレス
work .ds.b 256 * コマンドライン操作
******************************************************************************
* 非常駐ルーチンが使うスタック
******************************************************************************
.stack
.even
.ds.l 512
initsp:
******************************************************************************
.end main